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"]
|
[id="{upid}-{api}-request"]
|
||||||
==== Execution
|
==== 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
|
to manually throttle execution of a watch's actions. A watch can be acknowledged
|
||||||
through the following request:
|
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>>
|
| Bucket selector aggregation | <<painless-bucket-selector-agg-context, Painless Documentation>>
|
||||||
| {ref}/search-aggregations-pipeline-bucket-selector-aggregation.html[Elasticsearch Documentation]
|
| {ref}/search-aggregations-pipeline-bucket-selector-aggregation.html[Elasticsearch Documentation]
|
||||||
| Watcher condition | <<painless-watcher-condition-context, Painless 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>>
|
| 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[]
|
include::painless-contexts/index.asciidoc[]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[[painless-watcher-condition-context]]
|
[[painless-watcher-condition-context]]
|
||||||
=== 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.
|
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.
|
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)::
|
`ctx['payload']` (`Map`, read-only)::
|
||||||
The accessible watch data based upon the
|
The accessible watch data based upon the
|
||||||
{xpack-ref}/input.html[watch input].
|
{ref}/input.html[watch input].
|
||||||
|
|
||||||
*API*
|
*API*
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[[painless-watcher-transform-context]]
|
[[painless-watcher-transform-context]]
|
||||||
=== 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.
|
to transform a payload into a new payload for further use in the watch.
|
||||||
Transform scripts return an Object value of the new payload.
|
Transform scripts return an Object value of the new payload.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[[analysis-icu]]
|
[[analysis-icu]]
|
||||||
=== ICU Analysis Plugin
|
=== 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]
|
adding extended Unicode support using the http://site.icu-project.org/[ICU]
|
||||||
libraries, including better analysis of Asian languages, Unicode
|
libraries, including better analysis of Asian languages, Unicode
|
||||||
normalization, Unicode-aware case folding, collation support, and
|
normalization, Unicode-aware case folding, collation support, and
|
||||||
|
|
|
@ -44,7 +44,7 @@ The API returns the following response:
|
||||||
["source","txt",subs="attributes,callouts"]
|
["source","txt",subs="attributes,callouts"]
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
name component version description
|
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-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-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.
|
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/<index>`
|
||||||
|
|
||||||
|
`GET /_cat/recovery`
|
||||||
|
|
||||||
|
|
||||||
[[cat-recovery-api-desc]]
|
[[cat-recovery-api-desc]]
|
||||||
==== {api-description-title}
|
==== {api-description-title}
|
||||||
|
@ -37,14 +39,20 @@ include::{docdir}/rest-api/common-parms.asciidoc[tag=index]
|
||||||
[[cat-recovery-query-params]]
|
[[cat-recovery-query-params]]
|
||||||
==== {api-query-parms-title}
|
==== {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=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=http-format]
|
||||||
|
|
||||||
include::{docdir}/rest-api/common-parms.asciidoc[tag=cat-h]
|
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=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=local]
|
||||||
|
|
||||||
include::{docdir}/rest-api/common-parms.asciidoc[tag=master-timeout]
|
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
|
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}
|
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
|
IMPORTANT: The system key is a symmetric key, so the same key must be used on
|
||||||
every node in the cluster.
|
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
|
| `schedule` | A periodic or absolute time schedule. Supports all values
|
||||||
supported by the cron scheduler:
|
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.
|
| `name` | A name automatically given to each snapshot performed by this policy.
|
||||||
Supports the same <<date-math-index-names,date math>> supported in index
|
Supports the same <<date-math-index-names,date math>> supported in index
|
||||||
|
|
|
@ -97,7 +97,7 @@ PUT /_slm/policy/nightly-snapshots
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
// TEST[continued]
|
// TEST[continued]
|
||||||
<1> when the snapshot should be taken, using
|
<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
|
case at 1:30AM each day
|
||||||
<2> whe name each snapshot should be given, using
|
<2> whe name each snapshot should be given, using
|
||||||
<<date-math-index-names,date math>> to include the current date in the name
|
<<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
|
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
|
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
|
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
|
The allocation of replica shards which become unassigned because a node has
|
||||||
left can be delayed with the `index.unassigned.node_left.delayed_timeout`
|
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::security/index.asciidoc[]
|
||||||
|
|
||||||
|
include::{xes-repo-dir}/watcher/index.asciidoc[]
|
||||||
|
|
||||||
include::commands/index.asciidoc[]
|
include::commands/index.asciidoc[]
|
||||||
|
|
||||||
include::how-to.asciidoc[]
|
include::how-to.asciidoc[]
|
||||||
|
|
|
@ -1,5 +1,32 @@
|
||||||
[[indices-flush]]
|
[[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
|
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
|
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
|
indicates that {es} has flushed all the documents that were indexed before the
|
||||||
flush API was called.
|
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]
|
[source,console]
|
||||||
--------------------------------------------------
|
----
|
||||||
POST twitter/_flush
|
POST /kimchy/_flush
|
||||||
--------------------------------------------------
|
----
|
||||||
// TEST[setup:twitter]
|
// 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]]
|
[[flush-multi-index]]
|
||||||
==== Multi Index
|
===== Flush several indices
|
||||||
|
|
||||||
The flush API can be applied to more than one index with a single call, or even
|
|
||||||
on `_all` the indices.
|
|
||||||
|
|
||||||
[source,console]
|
[source,console]
|
||||||
--------------------------------------------------
|
----
|
||||||
POST kimchy,elasticsearch/_flush
|
POST /kimchy,elasticsearch/_flush
|
||||||
|
----
|
||||||
POST _flush
|
|
||||||
--------------------------------------------------
|
|
||||||
// TEST[s/^/PUT kimchy\nPUT elasticsearch\n/]
|
// TEST[s/^/PUT kimchy\nPUT elasticsearch\n/]
|
||||||
|
|
||||||
|
|
||||||
[float]
|
[[flush-api-all-ex]]
|
||||||
[[synced-flush-api]]
|
===== Flush all indices
|
||||||
==== Synced Flush
|
|
||||||
|
|
||||||
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>>.
|
<<ingest,ingest node>>.
|
||||||
|
|
||||||
For more information about typical monitoring architectures,
|
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:
|
. 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.
|
number of Logstash nodes or Beats.
|
||||||
|
|
||||||
For more information about typical monitoring architectures, see
|
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
|
monitoring cluster prevents production cluster outages from impacting your
|
||||||
ability to access your monitoring data. It also prevents monitoring activities
|
ability to access your monitoring data. It also prevents monitoring activities
|
||||||
from impacting the performance of your production cluster. See
|
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>>
|
* <<monitoring-overview>>
|
||||||
* <<how-monitoring-works>>
|
* <<how-monitoring-works>>
|
||||||
|
* <<monitoring-production>>
|
||||||
* <<collecting-monitoring-data>>
|
* <<collecting-monitoring-data>>
|
||||||
* <<configuring-metricbeat>>
|
* <<configuring-metricbeat>>
|
||||||
* <<configuring-filebeat>>
|
* <<configuring-filebeat>>
|
||||||
* <<config-monitoring-indices>>
|
* <<config-monitoring-indices>>
|
||||||
* <<es-monitoring-collectors>>
|
* <<es-monitoring-collectors>>
|
||||||
* <<es-monitoring-exporters>>
|
* <<es-monitoring-exporters>>
|
||||||
|
* <<monitoring-troubleshooting>>
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
|
@ -23,6 +25,8 @@ include::overview.asciidoc[]
|
||||||
|
|
||||||
include::how-monitoring-works.asciidoc[]
|
include::how-monitoring-works.asciidoc[]
|
||||||
|
|
||||||
|
include::production.asciidoc[]
|
||||||
|
|
||||||
include::collecting-monitoring-data.asciidoc[]
|
include::collecting-monitoring-data.asciidoc[]
|
||||||
include::pause-export.asciidoc[]
|
include::pause-export.asciidoc[]
|
||||||
|
|
||||||
|
@ -37,3 +41,5 @@ include::collectors.asciidoc[]
|
||||||
include::exporters.asciidoc[]
|
include::exporters.asciidoc[]
|
||||||
include::local-export.asciidoc[]
|
include::local-export.asciidoc[]
|
||||||
include::http-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"]
|
[role="exclude",id="indices-synced-flush"]
|
||||||
=== Synced flush API
|
=== Synced flush API
|
||||||
See <<synced-flush-api>>.
|
See <<indices-synced-flush-api>>.
|
||||||
|
|
||||||
[role="exclude",id="_repositories"]
|
[role="exclude",id="_repositories"]
|
||||||
=== Snapshot 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[]
|
tag::index-alias[]
|
||||||
Comma-separated list or wildcard expression of index alias names
|
Comma-separated list or wildcard expression of index alias names
|
||||||
used to limit the request.
|
used to limit the request.
|
||||||
|
@ -67,6 +75,14 @@ tag::default_operator[]
|
||||||
Defaults to `OR`.
|
Defaults to `OR`.
|
||||||
end::default_operator[]
|
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[]
|
tag::df[]
|
||||||
`df`::
|
`df`::
|
||||||
(Optional, string) Field to use as default where no field prefix is
|
(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`.
|
that are **not** loaded into memory. Defaults to `false`.
|
||||||
end::include-unloaded-segments[]
|
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[]
|
tag::index[]
|
||||||
`<index>`::
|
`<index>`::
|
||||||
(Optional, string) Comma-separated list or wildcard expression of index names
|
(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
|
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.
|
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
|
Use an HTTP exporter to send data to a separate monitoring cluster. For more
|
||||||
information, see <<local-exporter-settings,Local Exporter Settings>>,
|
information, see <<local-exporter-settings,Local exporter settings>>,
|
||||||
<<http-exporter-settings,HTTP Exporter Settings>>, and
|
<<http-exporter-settings,HTTP exporter settings>>, and
|
||||||
{xpack-ref}/how-monitoring-works.html[How Monitoring Works].
|
<<how-monitoring-works>>.
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
[[local-exporter-settings]]
|
[[local-exporter-settings]]
|
||||||
|
|
|
@ -27,14 +27,12 @@ Set to `false` to disable {watcher} on the node.
|
||||||
`xpack.watcher.encrypt_sensitive_data`::
|
`xpack.watcher.encrypt_sensitive_data`::
|
||||||
Set to `true` to encrypt sensitive data. If this setting is enabled, you
|
Set to `true` to encrypt sensitive data. If this setting is enabled, you
|
||||||
must also specify the `xpack.watcher.encryption_key` setting. For more
|
must also specify the `xpack.watcher.encryption_key` setting. For more
|
||||||
information, see
|
information, see <<encrypting-data>>.
|
||||||
{xpack-ref}/encrypting-data.html[Encrypting sensitive data in {watcher}].
|
|
||||||
|
|
||||||
`xpack.watcher.encryption_key` (<<secure-settings,Secure>>)::
|
`xpack.watcher.encryption_key` (<<secure-settings,Secure>>)::
|
||||||
Specifies the path to a file that contains a key for encrypting sensitive data.
|
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
|
If `xpack.watcher.encrypt_sensitive_data` is set to `true`, this setting is
|
||||||
required. For more information, see
|
required. For more information, see <<encrypting-data>>.
|
||||||
{xpack-ref}/encrypting-data.html[Encrypting sensitive data in {watcher}].
|
|
||||||
|
|
||||||
`xpack.watcher.history.cleaner_service.enabled`::
|
`xpack.watcher.history.cleaner_service.enabled`::
|
||||||
added:[6.3.0,Default changed to `true`.]
|
added:[6.3.0,Default changed to `true`.]
|
||||||
|
@ -88,7 +86,7 @@ include::ssl-settings.asciidoc[]
|
||||||
==== Email Notification Settings
|
==== Email Notification Settings
|
||||||
You can configure the following email notification settings in
|
You can configure the following email notification settings in
|
||||||
`elasticsearch.yml`. For more information about sending notifications
|
`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`::
|
`xpack.notification.email.account`::
|
||||||
Specifies account information for sending notifications via email. You
|
Specifies account information for sending notifications via email. You
|
||||||
|
@ -98,14 +96,15 @@ can specify the following email account attributes:
|
||||||
[[email-account-attributes]]
|
[[email-account-attributes]]
|
||||||
|
|
||||||
`profile` (<<cluster-update-settings,Dynamic>>);;
|
`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
|
messages that are sent from the account. Valid values: `standard`, `gmail` and
|
||||||
`outlook`. Defaults to `standard`.
|
`outlook`. Defaults to `standard`.
|
||||||
|
|
||||||
`email_defaults.*` (<<cluster-update-settings,Dynamic>>);;
|
`email_defaults.*` (<<cluster-update-settings,Dynamic>>);;
|
||||||
An optional set of email attributes to use as defaults
|
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[
|
for the emails sent from the account. See
|
||||||
Email Action Attributes] for the supported attributes.
|
<<email-action-attributes>> for the supported
|
||||||
|
attributes.
|
||||||
|
|
||||||
`smtp.auth` (<<cluster-update-settings,Dynamic>>);;
|
`smtp.auth` (<<cluster-update-settings,Dynamic>>);;
|
||||||
Set to `true` to attempt to authenticate the user using the
|
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`::
|
`xpack.notification.email.html.sanitization.allow`::
|
||||||
Specifies the HTML elements that are allowed in email notifications. For
|
Specifies the HTML elements that are allowed in email notifications. For
|
||||||
more information, see {xpack-ref}/actions-email.html#email-html-sanitization[Configuring HTML
|
more information, see
|
||||||
Sanitization Options]. You can specify individual HTML elements
|
<<email-html-sanitization>>. You can
|
||||||
and the following HTML feature groups:
|
specify individual HTML elements and the following HTML feature groups:
|
||||||
+
|
+
|
||||||
--
|
--
|
||||||
[[html-feature-groups]]
|
[[html-feature-groups]]
|
||||||
|
@ -229,7 +228,7 @@ include::ssl-settings.asciidoc[]
|
||||||
==== Slack Notification Settings
|
==== Slack Notification Settings
|
||||||
You can configure the following Slack notification settings in
|
You can configure the following Slack notification settings in
|
||||||
`elasticsearch.yml`. For more information about sending notifications
|
`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` ::
|
`xpack.notification.slack` ::
|
||||||
Specifies account information for sending notifications
|
Specifies account information for sending notifications
|
||||||
|
@ -270,7 +269,7 @@ via Slack. You can specify the following Slack account attributes:
|
||||||
==== Jira Notification Settings
|
==== Jira Notification Settings
|
||||||
You can configure the following Jira notification settings in
|
You can configure the following Jira notification settings in
|
||||||
`elasticsearch.yml`. For more information about using notifications
|
`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` ::
|
`xpack.notification.jira` ::
|
||||||
Specifies account information for using notifications to create
|
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`;;
|
`issue_defaults`;;
|
||||||
Default fields values for the issue created in Jira. See
|
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.
|
Optional.
|
||||||
--
|
--
|
||||||
|
|
||||||
|
@ -299,7 +298,7 @@ issues in Jira. You can specify the following Jira account attributes:
|
||||||
==== PagerDuty Notification Settings
|
==== PagerDuty Notification Settings
|
||||||
You can configure the following PagerDuty notification settings in
|
You can configure the following PagerDuty notification settings in
|
||||||
`elasticsearch.yml`. For more information about sending notifications
|
`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]]
|
[[pagerduty-account-attributes]]
|
||||||
|
@ -318,8 +317,9 @@ PagerDuty API key] to use to access PagerDuty. Required.
|
||||||
--
|
--
|
||||||
+
|
+
|
||||||
`event_defaults`;;
|
`event_defaults`;;
|
||||||
Default values for {xpack-ref}/actions-pagerduty.html#pagerduty-event-trigger-incident-attributes[
|
Default values for
|
||||||
PagerDuty event attributes]. Optional.
|
<<pagerduty-event-trigger-incident-attributes,PagerDuty event attributes>>.
|
||||||
|
Optional.
|
||||||
+
|
+
|
||||||
--
|
--
|
||||||
`description`::
|
`description`::
|
||||||
|
|
|
@ -14,8 +14,7 @@ If you use {watcher} and have chosen to encrypt sensitive data (by setting
|
||||||
the secure settings store.
|
the secure settings store.
|
||||||
|
|
||||||
To pass this bootstrap check, you must set the `xpack.watcher.encryption_key`
|
To pass this bootstrap check, you must set the `xpack.watcher.encryption_key`
|
||||||
on each node in the cluster. For more information, see
|
on each node in the cluster. For more information, see <<encrypting-data>>.
|
||||||
{xpack-ref}/encrypting-data.html[Encrypting Sensitive Data in {watcher}].
|
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
=== PKI realm check
|
=== 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).
|
function as the maximum number of second fractional digits returned is 3 (milliseconds).
|
||||||
|
|
||||||
[[sql-functions-datetime-trunc]]
|
[[sql-functions-datetime-trunc]]
|
||||||
==== `DATE_TRUNC`
|
==== `DATE_TRUNC/DATETRUNC`
|
||||||
|
|
||||||
.Synopsis:
|
.Synopsis:
|
||||||
[source, sql]
|
[source, sql]
|
||||||
|
@ -269,7 +269,7 @@ DATE_TRUNC(
|
||||||
.Description:
|
.Description:
|
||||||
|
|
||||||
Truncate the date/datetime to the specified unit by setting all fields that are less significant than the specified
|
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="^,^"]
|
[cols="^,^"]
|
||||||
|===
|
|===
|
||||||
|
|
|
@ -20,7 +20,7 @@ include::disable-shard-alloc.asciidoc[]
|
||||||
. *Stop indexing and perform a synced flush.*
|
. *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.
|
recovery.
|
||||||
|
|
||||||
include::synced-flush.asciidoc[]
|
include::synced-flush.asciidoc[]
|
||||||
|
|
|
@ -30,7 +30,7 @@ include::disable-shard-alloc.asciidoc[]
|
||||||
--
|
--
|
||||||
While you can continue indexing during the upgrade, shard recovery
|
While you can continue indexing during the upgrade, shard recovery
|
||||||
is much faster if you temporarily stop non-essential indexing and perform a
|
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[]
|
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`.
|
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
|
recover. You can monitor the recovery status of individual shards by
|
||||||
submitting a <<cat-recovery,`_cat/recovery`>> request:
|
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
|
// ANTLR GENERATED CODE: DO NOT EDIT
|
||||||
package org.elasticsearch.painless.antlr;
|
package org.elasticsearch.painless.antlr;
|
||||||
import org.antlr.v4.runtime.Lexer;
|
|
||||||
import org.antlr.v4.runtime.CharStream;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Lexer;
|
||||||
import org.antlr.v4.runtime.TokenStream;
|
import org.antlr.v4.runtime.RuleContext;
|
||||||
import org.antlr.v4.runtime.*;
|
import org.antlr.v4.runtime.RuntimeMetaData;
|
||||||
import org.antlr.v4.runtime.atn.*;
|
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.dfa.DFA;
|
||||||
import org.antlr.v4.runtime.misc.*;
|
|
||||||
|
|
||||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||||
abstract class PainlessLexer extends Lexer {
|
abstract class PainlessLexer extends Lexer {
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
// ANTLR GENERATED CODE: DO NOT EDIT
|
// ANTLR GENERATED CODE: DO NOT EDIT
|
||||||
package org.elasticsearch.painless.antlr;
|
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.dfa.DFA;
|
||||||
import org.antlr.v4.runtime.*;
|
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||||
import org.antlr.v4.runtime.misc.*;
|
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||||
import org.antlr.v4.runtime.tree.*;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||||
class PainlessParser extends Parser {
|
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.SBlock;
|
||||||
import org.elasticsearch.painless.node.SBreak;
|
import org.elasticsearch.painless.node.SBreak;
|
||||||
import org.elasticsearch.painless.node.SCatch;
|
import org.elasticsearch.painless.node.SCatch;
|
||||||
|
import org.elasticsearch.painless.node.SClass;
|
||||||
import org.elasticsearch.painless.node.SContinue;
|
import org.elasticsearch.painless.node.SContinue;
|
||||||
import org.elasticsearch.painless.node.SDeclBlock;
|
import org.elasticsearch.painless.node.SDeclBlock;
|
||||||
import org.elasticsearch.painless.node.SDeclaration;
|
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.SIf;
|
||||||
import org.elasticsearch.painless.node.SIfElse;
|
import org.elasticsearch.painless.node.SIfElse;
|
||||||
import org.elasticsearch.painless.node.SReturn;
|
import org.elasticsearch.painless.node.SReturn;
|
||||||
import org.elasticsearch.painless.node.SClass;
|
|
||||||
import org.elasticsearch.painless.node.SThrow;
|
import org.elasticsearch.painless.node.SThrow;
|
||||||
import org.elasticsearch.painless.node.STry;
|
import org.elasticsearch.painless.node.STry;
|
||||||
import org.elasticsearch.painless.node.SWhile;
|
import org.elasticsearch.painless.node.SWhile;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -75,7 +76,7 @@ public abstract class ANode {
|
||||||
/**
|
/**
|
||||||
* Writes ASM based on the data collected during the analysis phase.
|
* 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.
|
* Create an error with location information pointing to this node.
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
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
|
* Called before a storeable node is loaded or stored. Used to load prefixes and
|
||||||
* push load/store constants onto the stack if necessary.
|
* 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.
|
* 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.
|
* 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
|
* 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.AnalyzerCaster;
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.DefBootstrap;
|
import org.elasticsearch.painless.DefBootstrap;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -250,8 +251,8 @@ public final class EAssignment extends AExpression {
|
||||||
* also read from.
|
* also read from.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
// For the case where the assignment represents a String concatenation
|
// For the case where the assignment represents a String concatenation
|
||||||
// we must, depending on the Java version, write a StringBuilder or
|
// we must, depending on the Java version, write a StringBuilder or
|
||||||
|
@ -261,86 +262,87 @@ public final class EAssignment extends AExpression {
|
||||||
int catElementStackSize = 0;
|
int catElementStackSize = 0;
|
||||||
|
|
||||||
if (cat) {
|
if (cat) {
|
||||||
catElementStackSize = writer.writeNewStrings();
|
catElementStackSize = methodWriter.writeNewStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cast the lhs to a storeable to perform the necessary operations to store the rhs.
|
// Cast the lhs to a storeable to perform the necessary operations to store the rhs.
|
||||||
AStoreable lhs = (AStoreable)this.lhs;
|
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) {
|
if (cat) {
|
||||||
// Handle the case where we are doing a compound assignment
|
// Handle the case where we are doing a compound assignment
|
||||||
// representing a String concatenation.
|
// 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
|
// before concat helper on stack
|
||||||
lhs.load(writer, globals); // read the current lhs's value
|
lhs.load(classWriter, methodWriter, globals); // read the current lhs's value
|
||||||
writer.writeAppendStrings(lhs.actual); // append the lhs's value using the StringBuilder
|
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
|
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
|
methodWriter.writeToStrings(); // put the value for string concat onto the stack
|
||||||
writer.writeCast(back); // if necessary, cast the String to the lhs actual type
|
methodWriter.writeCast(back); // if necessary, cast the String to the lhs actual type
|
||||||
|
|
||||||
if (lhs.read) {
|
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
|
// from dup the value onto the stack
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the lhs's value from the stack in its respective variable/field/array
|
lhs.store(classWriter, methodWriter, globals); // store the lhs's value from the stack in its respective variable/field/array
|
||||||
lhs.store(writer, globals);
|
|
||||||
} else if (operation != null) {
|
} else if (operation != null) {
|
||||||
// Handle the case where we are doing a compound assignment that
|
// Handle the case where we are doing a compound assignment that
|
||||||
// does not represent a String concatenation.
|
// does not represent a String concatenation.
|
||||||
|
|
||||||
writer.writeDup(lhs.accessElementCount(), 0); // if necessary, dup the previous lhs's value
|
methodWriter.writeDup(lhs.accessElementCount(), 0); // if necessary, dup the previous lhs's value
|
||||||
// to be both loaded from and stored to
|
// to be both loaded from and stored to
|
||||||
lhs.load(writer, globals); // load the current lhs's value
|
lhs.load(classWriter, methodWriter, globals); // load the current lhs's value
|
||||||
|
|
||||||
if (lhs.read && post) {
|
if (lhs.read && post) {
|
||||||
writer.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // dup the value if the lhs is also
|
methodWriter.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // dup the value if the
|
||||||
// read from and is a post increment
|
// lhs is also
|
||||||
|
// read from and is a post
|
||||||
|
// increment
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.writeCast(there); // if necessary cast the current lhs's value
|
methodWriter.writeCast(there); // if necessary cast the current lhs's value
|
||||||
// to the promotion type between the lhs and rhs types
|
// to the promotion type between the lhs and rhs types
|
||||||
rhs.write(writer, globals); // write the bytecode for the rhs
|
rhs.write(classWriter, methodWriter, globals); // write the bytecode for the rhs
|
||||||
|
|
||||||
// XXX: fix these types, but first we need def compound assignment tests.
|
// XXX: fix these types, but first we need def compound assignment tests.
|
||||||
// its tricky here as there are possibly explicit casts, too.
|
// its tricky here as there are possibly explicit casts, too.
|
||||||
// write the operation instruction for compound assignment
|
// write the operation instruction for compound assignment
|
||||||
if (promote == def.class) {
|
if (promote == def.class) {
|
||||||
writer.writeDynamicBinaryInstruction(
|
methodWriter.writeDynamicBinaryInstruction(
|
||||||
location, promote, def.class, def.class, operation, DefBootstrap.OPERATOR_COMPOUND_ASSIGNMENT);
|
location, promote, def.class, def.class, operation, DefBootstrap.OPERATOR_COMPOUND_ASSIGNMENT);
|
||||||
} else {
|
} 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) {
|
if (lhs.read && !post) {
|
||||||
// dup the value if the lhs is also read from and is not a post increment
|
methodWriter.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // dup the value if the lhs
|
||||||
writer.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount());
|
// 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(classWriter, methodWriter, globals); // store the lhs's value from the stack in its respective variable/field/array
|
||||||
lhs.store(writer, globals);
|
|
||||||
} else {
|
} else {
|
||||||
// Handle the case for a simple write.
|
// 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) {
|
if (lhs.read) {
|
||||||
// dup the value if the lhs is also read from
|
methodWriter.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount()); // dup the value if the lhs
|
||||||
writer.writeDup(MethodWriter.getType(lhs.actual).getSize(), lhs.accessElementCount());
|
// is also read from
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the lhs's value from the stack in its respective variable/field/array
|
lhs.store(classWriter, methodWriter, globals); // store the lhs's value from the stack in its respective variable/field/array
|
||||||
lhs.store(writer, globals);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.AnalyzerCaster;
|
import org.elasticsearch.painless.AnalyzerCaster;
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.DefBootstrap;
|
import org.elasticsearch.painless.DefBootstrap;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -626,44 +627,44 @@ public final class EBinary extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
if (promote == String.class && operation == Operation.ADD) {
|
if (promote == String.class && operation == Operation.ADD) {
|
||||||
if (!cat) {
|
if (!cat) {
|
||||||
writer.writeNewStrings();
|
methodWriter.writeNewStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
left.write(writer, globals);
|
left.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
if (!(left instanceof EBinary) || !((EBinary)left).cat) {
|
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) {
|
if (!(right instanceof EBinary) || !((EBinary)right).cat) {
|
||||||
writer.writeAppendStrings(right.actual);
|
methodWriter.writeAppendStrings(right.actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cat) {
|
if (!cat) {
|
||||||
writer.writeToStrings();
|
methodWriter.writeToStrings();
|
||||||
}
|
}
|
||||||
} else if (operation == Operation.FIND || operation == Operation.MATCH) {
|
} else if (operation == Operation.FIND || operation == Operation.MATCH) {
|
||||||
right.write(writer, globals);
|
right.write(classWriter, methodWriter, globals);
|
||||||
left.write(writer, globals);
|
left.write(classWriter, methodWriter, globals);
|
||||||
writer.invokeVirtual(org.objectweb.asm.Type.getType(Pattern.class), WriterConstants.PATTERN_MATCHER);
|
methodWriter.invokeVirtual(org.objectweb.asm.Type.getType(Pattern.class), WriterConstants.PATTERN_MATCHER);
|
||||||
|
|
||||||
if (operation == Operation.FIND) {
|
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) {
|
} 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 {
|
} else {
|
||||||
throw new IllegalStateException("Illegal tree structure.");
|
throw new IllegalStateException("Illegal tree structure.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
left.write(writer, globals);
|
left.write(classWriter, methodWriter, globals);
|
||||||
right.write(writer, globals);
|
right.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
if (promote == def.class || (shiftDistance != null && shiftDistance == def.class)) {
|
if (promote == def.class || (shiftDistance != null && shiftDistance == def.class)) {
|
||||||
// def calls adopt the wanted return value. if there was a narrowing cast,
|
// 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) {
|
if (originallyExplicit) {
|
||||||
flags |= DefBootstrap.OPERATOR_EXPLICIT_CAST;
|
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 {
|
} else {
|
||||||
writer.writeBinaryInstruction(location, actual, operation);
|
methodWriter.writeBinaryInstruction(location, actual, operation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -84,37 +85,37 @@ public final class EBool extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
if (operation == Operation.AND) {
|
if (operation == Operation.AND) {
|
||||||
Label fals = new Label();
|
Label fals = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
left.write(writer, globals);
|
left.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, fals);
|
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
|
||||||
right.write(writer, globals);
|
right.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, fals);
|
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
|
||||||
|
|
||||||
writer.push(true);
|
methodWriter.push(true);
|
||||||
writer.goTo(end);
|
methodWriter.goTo(end);
|
||||||
writer.mark(fals);
|
methodWriter.mark(fals);
|
||||||
writer.push(false);
|
methodWriter.push(false);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
} else if (operation == Operation.OR) {
|
} else if (operation == Operation.OR) {
|
||||||
Label tru = new Label();
|
Label tru = new Label();
|
||||||
Label fals = new Label();
|
Label fals = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
left.write(writer, globals);
|
left.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFNE, tru);
|
methodWriter.ifZCmp(Opcodes.IFNE, tru);
|
||||||
right.write(writer, globals);
|
right.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, fals);
|
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
|
||||||
|
|
||||||
writer.mark(tru);
|
methodWriter.mark(tru);
|
||||||
writer.push(true);
|
methodWriter.push(true);
|
||||||
writer.goTo(end);
|
methodWriter.goTo(end);
|
||||||
writer.mark(fals);
|
methodWriter.mark(fals);
|
||||||
writer.push(false);
|
methodWriter.push(false);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
} else {
|
} else {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -58,7 +59,7 @@ public final class EBoolean extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter adapter, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter adapter, Globals globals) {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -154,21 +155,21 @@ public final class ECallLocal extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
if (localMethod != null) {
|
if (localMethod != null) {
|
||||||
for (AExpression argument : arguments) {
|
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) {
|
} else if (importedMethod != null) {
|
||||||
for (AExpression argument : arguments) {
|
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()));
|
new Method(importedMethod.javaMethod.getName(), importedMethod.methodType.toMethodDescriptorString()));
|
||||||
} else if (classBinding != null) {
|
} else if (classBinding != null) {
|
||||||
String name = globals.addClassBinding(classBinding.javaConstructor.getDeclaringClass());
|
String name = globals.addClassBinding(classBinding.javaConstructor.getDeclaringClass());
|
||||||
|
@ -177,45 +178,45 @@ public final class ECallLocal extends AExpression {
|
||||||
|
|
||||||
Label nonNull = new Label();
|
Label nonNull = new Label();
|
||||||
|
|
||||||
writer.loadThis();
|
methodWriter.loadThis();
|
||||||
writer.getField(CLASS_TYPE, name, type);
|
methodWriter.getField(CLASS_TYPE, name, type);
|
||||||
writer.ifNonNull(nonNull);
|
methodWriter.ifNonNull(nonNull);
|
||||||
writer.loadThis();
|
methodWriter.loadThis();
|
||||||
writer.newInstance(type);
|
methodWriter.newInstance(type);
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
|
|
||||||
if (classBindingOffset == 1) {
|
if (classBindingOffset == 1) {
|
||||||
writer.loadThis();
|
methodWriter.loadThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int argument = 0; argument < javaConstructorParameterCount; ++argument) {
|
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));
|
methodWriter.invokeConstructor(type, Method.getMethod(classBinding.javaConstructor));
|
||||||
writer.putField(CLASS_TYPE, name, type);
|
methodWriter.putField(CLASS_TYPE, name, type);
|
||||||
|
|
||||||
writer.mark(nonNull);
|
methodWriter.mark(nonNull);
|
||||||
writer.loadThis();
|
methodWriter.loadThis();
|
||||||
writer.getField(CLASS_TYPE, name, type);
|
methodWriter.getField(CLASS_TYPE, name, type);
|
||||||
|
|
||||||
for (int argument = 0; argument < classBinding.javaMethod.getParameterCount(); ++argument) {
|
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) {
|
} else if (instanceBinding != null) {
|
||||||
String name = globals.addInstanceBinding(instanceBinding.targetInstance);
|
String name = globals.addInstanceBinding(instanceBinding.targetInstance);
|
||||||
Type type = Type.getType(instanceBinding.targetInstance.getClass());
|
Type type = Type.getType(instanceBinding.targetInstance.getClass());
|
||||||
|
|
||||||
writer.loadThis();
|
methodWriter.loadThis();
|
||||||
writer.getStatic(CLASS_TYPE, name, type);
|
methodWriter.getStatic(CLASS_TYPE, name, type);
|
||||||
|
|
||||||
for (int argument = 0; argument < instanceBinding.javaMethod.getParameterCount(); ++argument) {
|
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 {
|
} else {
|
||||||
throw new IllegalStateException("Illegal tree structure.");
|
throw new IllegalStateException("Illegal tree structure.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.DefBootstrap;
|
import org.elasticsearch.painless.DefBootstrap;
|
||||||
import org.elasticsearch.painless.FunctionRef;
|
import org.elasticsearch.painless.FunctionRef;
|
||||||
|
@ -87,22 +88,22 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
if (defPointer != null) {
|
if (defPointer != null) {
|
||||||
// dynamic interface: push captured parameter on stack
|
// dynamic interface: push captured parameter on stack
|
||||||
// TODO: don't do this: its just to cutover :)
|
// TODO: don't do this: its just to cutover :)
|
||||||
writer.push((String)null);
|
methodWriter.push((String)null);
|
||||||
writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
|
||||||
} else if (ref == null) {
|
} else if (ref == null) {
|
||||||
// typed interface, dynamic implementation
|
// 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));
|
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 {
|
} else {
|
||||||
// typed interface, typed implementation
|
// typed interface, typed implementation
|
||||||
writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
|
||||||
writer.invokeLambdaCall(ref);
|
methodWriter.invokeLambdaCall(ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -61,10 +62,10 @@ final class ECast extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
child.write(writer, globals);
|
child.write(classWriter, methodWriter, globals);
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.writeCast(cast);
|
methodWriter.writeCast(cast);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.AnalyzerCaster;
|
import org.elasticsearch.painless.AnalyzerCaster;
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.DefBootstrap;
|
import org.elasticsearch.painless.DefBootstrap;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -435,13 +436,13 @@ public final class EComp extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
left.write(writer, globals);
|
left.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
if (!right.isNull) {
|
if (!right.isNull) {
|
||||||
right.write(writer, globals);
|
right.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
Label jump = new Label();
|
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) {
|
if (promotedType == void.class || promotedType == byte.class || promotedType == short.class || promotedType == char.class) {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
} else if (promotedType == boolean.class) {
|
} else if (promotedType == boolean.class) {
|
||||||
if (eq) writer.ifCmp(type, MethodWriter.EQ, jump);
|
if (eq) methodWriter.ifCmp(type, MethodWriter.EQ, jump);
|
||||||
else if (ne) writer.ifCmp(type, MethodWriter.NE, jump);
|
else if (ne) methodWriter.ifCmp(type, MethodWriter.NE, jump);
|
||||||
else {
|
else {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
} else if (promotedType == int.class || promotedType == long.class || promotedType == float.class || promotedType == double.class) {
|
} else if (promotedType == int.class || promotedType == long.class || promotedType == float.class || promotedType == double.class) {
|
||||||
if (eq) writer.ifCmp(type, MethodWriter.EQ, jump);
|
if (eq) methodWriter.ifCmp(type, MethodWriter.EQ, jump);
|
||||||
else if (ne) writer.ifCmp(type, MethodWriter.NE, jump);
|
else if (ne) methodWriter.ifCmp(type, MethodWriter.NE, jump);
|
||||||
else if (lt) writer.ifCmp(type, MethodWriter.LT, jump);
|
else if (lt) methodWriter.ifCmp(type, MethodWriter.LT, jump);
|
||||||
else if (lte) writer.ifCmp(type, MethodWriter.LE, jump);
|
else if (lte) methodWriter.ifCmp(type, MethodWriter.LE, jump);
|
||||||
else if (gt) writer.ifCmp(type, MethodWriter.GT, jump);
|
else if (gt) methodWriter.ifCmp(type, MethodWriter.GT, jump);
|
||||||
else if (gte) writer.ifCmp(type, MethodWriter.GE, jump);
|
else if (gte) methodWriter.ifCmp(type, MethodWriter.GE, jump);
|
||||||
else {
|
else {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
@ -483,33 +484,33 @@ public final class EComp extends AExpression {
|
||||||
|
|
||||||
if (eq) {
|
if (eq) {
|
||||||
if (right.isNull) {
|
if (right.isNull) {
|
||||||
writer.ifNull(jump);
|
methodWriter.ifNull(jump);
|
||||||
} else if (!left.isNull && operation == Operation.EQ) {
|
} 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;
|
writejump = false;
|
||||||
} else {
|
} else {
|
||||||
writer.ifCmp(type, MethodWriter.EQ, jump);
|
methodWriter.ifCmp(type, MethodWriter.EQ, jump);
|
||||||
}
|
}
|
||||||
} else if (ne) {
|
} else if (ne) {
|
||||||
if (right.isNull) {
|
if (right.isNull) {
|
||||||
writer.ifNonNull(jump);
|
methodWriter.ifNonNull(jump);
|
||||||
} else if (!left.isNull && operation == Operation.NE) {
|
} else if (!left.isNull && operation == Operation.NE) {
|
||||||
writer.invokeDefCall("eq", descriptor, DefBootstrap.BINARY_OPERATOR, DefBootstrap.OPERATOR_ALLOWS_NULL);
|
methodWriter.invokeDefCall("eq", descriptor, DefBootstrap.BINARY_OPERATOR, DefBootstrap.OPERATOR_ALLOWS_NULL);
|
||||||
writer.ifZCmp(MethodWriter.EQ, jump);
|
methodWriter.ifZCmp(MethodWriter.EQ, jump);
|
||||||
} else {
|
} else {
|
||||||
writer.ifCmp(type, MethodWriter.NE, jump);
|
methodWriter.ifCmp(type, MethodWriter.NE, jump);
|
||||||
}
|
}
|
||||||
} else if (lt) {
|
} else if (lt) {
|
||||||
writer.invokeDefCall("lt", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
|
methodWriter.invokeDefCall("lt", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
|
||||||
writejump = false;
|
writejump = false;
|
||||||
} else if (lte) {
|
} else if (lte) {
|
||||||
writer.invokeDefCall("lte", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
|
methodWriter.invokeDefCall("lte", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
|
||||||
writejump = false;
|
writejump = false;
|
||||||
} else if (gt) {
|
} else if (gt) {
|
||||||
writer.invokeDefCall("gt", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
|
methodWriter.invokeDefCall("gt", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
|
||||||
writejump = false;
|
writejump = false;
|
||||||
} else if (gte) {
|
} else if (gte) {
|
||||||
writer.invokeDefCall("gte", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
|
methodWriter.invokeDefCall("gte", descriptor, DefBootstrap.BINARY_OPERATOR, 0);
|
||||||
writejump = false;
|
writejump = false;
|
||||||
} else {
|
} else {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
|
@ -517,21 +518,21 @@ public final class EComp extends AExpression {
|
||||||
} else {
|
} else {
|
||||||
if (eq) {
|
if (eq) {
|
||||||
if (right.isNull) {
|
if (right.isNull) {
|
||||||
writer.ifNull(jump);
|
methodWriter.ifNull(jump);
|
||||||
} else if (operation == Operation.EQ) {
|
} else if (operation == Operation.EQ) {
|
||||||
writer.invokeStatic(OBJECTS_TYPE, EQUALS);
|
methodWriter.invokeStatic(OBJECTS_TYPE, EQUALS);
|
||||||
writejump = false;
|
writejump = false;
|
||||||
} else {
|
} else {
|
||||||
writer.ifCmp(type, MethodWriter.EQ, jump);
|
methodWriter.ifCmp(type, MethodWriter.EQ, jump);
|
||||||
}
|
}
|
||||||
} else if (ne) {
|
} else if (ne) {
|
||||||
if (right.isNull) {
|
if (right.isNull) {
|
||||||
writer.ifNonNull(jump);
|
methodWriter.ifNonNull(jump);
|
||||||
} else if (operation == Operation.NE) {
|
} else if (operation == Operation.NE) {
|
||||||
writer.invokeStatic(OBJECTS_TYPE, EQUALS);
|
methodWriter.invokeStatic(OBJECTS_TYPE, EQUALS);
|
||||||
writer.ifZCmp(MethodWriter.EQ, jump);
|
methodWriter.ifZCmp(MethodWriter.EQ, jump);
|
||||||
} else {
|
} else {
|
||||||
writer.ifCmp(type, MethodWriter.NE, jump);
|
methodWriter.ifCmp(type, MethodWriter.NE, jump);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
|
@ -539,11 +540,11 @@ public final class EComp extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writejump) {
|
if (writejump) {
|
||||||
writer.push(false);
|
methodWriter.push(false);
|
||||||
writer.goTo(end);
|
methodWriter.goTo(end);
|
||||||
writer.mark(jump);
|
methodWriter.mark(jump);
|
||||||
writer.push(true);
|
methodWriter.push(true);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.AnalyzerCaster;
|
import org.elasticsearch.painless.AnalyzerCaster;
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -96,20 +97,20 @@ public final class EConditional extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
Label fals = new Label();
|
Label fals = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
condition.write(writer, globals);
|
condition.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, fals);
|
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
|
||||||
|
|
||||||
left.write(writer, globals);
|
left.write(classWriter, methodWriter, globals);
|
||||||
writer.goTo(end);
|
methodWriter.goTo(end);
|
||||||
writer.mark(fals);
|
methodWriter.mark(fals);
|
||||||
right.write(writer, globals);
|
right.write(classWriter, methodWriter, globals);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -75,16 +76,16 @@ final class EConstant extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
if (actual == String.class) writer.push((String)constant);
|
if (actual == String.class) methodWriter.push((String)constant);
|
||||||
else if (actual == double.class) writer.push((double)constant);
|
else if (actual == double.class) methodWriter.push((double)constant);
|
||||||
else if (actual == float.class) writer.push((float)constant);
|
else if (actual == float.class) methodWriter.push((float)constant);
|
||||||
else if (actual == long.class) writer.push((long)constant);
|
else if (actual == long.class) methodWriter.push((long)constant);
|
||||||
else if (actual == int.class) writer.push((int)constant);
|
else if (actual == int.class) methodWriter.push((int)constant);
|
||||||
else if (actual == char.class) writer.push((char)constant);
|
else if (actual == char.class) methodWriter.push((char)constant);
|
||||||
else if (actual == short.class) writer.push((short)constant);
|
else if (actual == short.class) methodWriter.push((short)constant);
|
||||||
else if (actual == byte.class) writer.push((byte)constant);
|
else if (actual == byte.class) methodWriter.push((byte)constant);
|
||||||
else if (actual == boolean.class) writer.push((boolean)constant);
|
else if (actual == boolean.class) methodWriter.push((boolean)constant);
|
||||||
else {
|
else {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -79,7 +80,7 @@ public final class EDecimal extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.AnalyzerCaster;
|
import org.elasticsearch.painless.AnalyzerCaster;
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -99,17 +100,17 @@ public class EElvis extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
lhs.write(writer, globals);
|
lhs.write(classWriter, methodWriter, globals);
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
writer.ifNonNull(end);
|
methodWriter.ifNonNull(end);
|
||||||
writer.pop();
|
methodWriter.pop();
|
||||||
rhs.write(writer, globals);
|
rhs.write(classWriter, methodWriter, globals);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -68,7 +69,7 @@ public final class EExplicit extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.FunctionRef;
|
import org.elasticsearch.painless.FunctionRef;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -71,13 +72,13 @@ public final class EFunctionRef extends AExpression implements ILambda {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.invokeLambdaCall(ref);
|
methodWriter.invokeLambdaCall(ref);
|
||||||
} else {
|
} else {
|
||||||
// TODO: don't do this: its just to cutover :)
|
// 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;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -87,19 +88,19 @@ public final class EInstanceof extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
// primitive types
|
// primitive types
|
||||||
if (primitiveExpression) {
|
if (primitiveExpression) {
|
||||||
// run the expression anyway (who knows what it does)
|
// run the expression anyway (who knows what it does)
|
||||||
expression.write(writer, globals);
|
expression.write(classWriter, methodWriter, globals);
|
||||||
// discard its result
|
// 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.
|
// push our result: its a primitive so it cannot be null.
|
||||||
writer.push(resolvedType.isAssignableFrom(expressionType));
|
methodWriter.push(resolvedType.isAssignableFrom(expressionType));
|
||||||
} else {
|
} else {
|
||||||
// ordinary instanceof
|
// ordinary instanceof
|
||||||
expression.write(writer, globals);
|
expression.write(classWriter, methodWriter, globals);
|
||||||
writer.instanceOf(org.objectweb.asm.Type.getType(resolvedType));
|
methodWriter.instanceOf(org.objectweb.asm.Type.getType(resolvedType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.FunctionRef;
|
import org.elasticsearch.painless.FunctionRef;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -196,23 +197,23 @@ public final class ELambda extends AExpression implements ILambda {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
// load captures
|
// load captures
|
||||||
for (Variable capture : 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 {
|
} else {
|
||||||
// placeholder
|
// placeholder
|
||||||
writer.push((String)null);
|
methodWriter.push((String)null);
|
||||||
// load captures
|
// load captures
|
||||||
for (Variable capture : 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;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -97,19 +98,19 @@ public final class EListInit extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
writer.newInstance(MethodWriter.getType(actual));
|
methodWriter.newInstance(MethodWriter.getType(actual));
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
writer.invokeConstructor(
|
methodWriter.invokeConstructor(
|
||||||
Type.getType(constructor.javaConstructor.getDeclaringClass()), Method.getMethod(constructor.javaConstructor));
|
Type.getType(constructor.javaConstructor.getDeclaringClass()), Method.getMethod(constructor.javaConstructor));
|
||||||
|
|
||||||
for (AExpression value : values) {
|
for (AExpression value : values) {
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
value.write(writer, globals);
|
value.write(classWriter, methodWriter, globals);
|
||||||
writer.invokeMethodCall(method);
|
methodWriter.invokeMethodCall(method);
|
||||||
writer.pop();
|
methodWriter.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -120,23 +121,23 @@ public final class EMapInit extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
writer.newInstance(MethodWriter.getType(actual));
|
methodWriter.newInstance(MethodWriter.getType(actual));
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
writer.invokeConstructor(
|
methodWriter.invokeConstructor(
|
||||||
Type.getType(constructor.javaConstructor.getDeclaringClass()), Method.getMethod(constructor.javaConstructor));
|
Type.getType(constructor.javaConstructor.getDeclaringClass()), Method.getMethod(constructor.javaConstructor));
|
||||||
|
|
||||||
for (int index = 0; index < keys.size(); ++index) {
|
for (int index = 0; index < keys.size(); ++index) {
|
||||||
AExpression key = keys.get(index);
|
AExpression key = keys.get(index);
|
||||||
AExpression value = values.get(index);
|
AExpression value = values.get(index);
|
||||||
|
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
key.write(writer, globals);
|
key.write(classWriter, methodWriter, globals);
|
||||||
value.write(writer, globals);
|
value.write(classWriter, methodWriter, globals);
|
||||||
writer.invokeMethodCall(method);
|
methodWriter.invokeMethodCall(method);
|
||||||
writer.pop();
|
methodWriter.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -85,30 +86,30 @@ public final class ENewArray extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
if (initialize) {
|
if (initialize) {
|
||||||
writer.push(arguments.size());
|
methodWriter.push(arguments.size());
|
||||||
writer.newArray(MethodWriter.getType(actual.getComponentType()));
|
methodWriter.newArray(MethodWriter.getType(actual.getComponentType()));
|
||||||
|
|
||||||
for (int index = 0; index < arguments.size(); ++index) {
|
for (int index = 0; index < arguments.size(); ++index) {
|
||||||
AExpression argument = arguments.get(index);
|
AExpression argument = arguments.get(index);
|
||||||
|
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
writer.push(index);
|
methodWriter.push(index);
|
||||||
argument.write(writer, globals);
|
argument.write(classWriter, methodWriter, globals);
|
||||||
writer.arrayStore(MethodWriter.getType(actual.getComponentType()));
|
methodWriter.arrayStore(MethodWriter.getType(actual.getComponentType()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (AExpression argument : arguments) {
|
for (AExpression argument : arguments) {
|
||||||
argument.write(writer, globals);
|
argument.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments.size() > 1) {
|
if (arguments.size() > 1) {
|
||||||
writer.visitMultiANewArrayInsn(MethodWriter.getType(actual).getDescriptor(), arguments.size());
|
methodWriter.visitMultiANewArrayInsn(MethodWriter.getType(actual).getDescriptor(), arguments.size());
|
||||||
} else {
|
} else {
|
||||||
writer.newArray(MethodWriter.getType(actual.getComponentType()));
|
methodWriter.newArray(MethodWriter.getType(actual.getComponentType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.FunctionRef;
|
import org.elasticsearch.painless.FunctionRef;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -85,13 +86,13 @@ public final class ENewArrayFunctionRef extends AExpression implements ILambda {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.invokeLambdaCall(ref);
|
methodWriter.invokeLambdaCall(ref);
|
||||||
} else {
|
} else {
|
||||||
// push a null instruction as a placeholder for future lambda instructions
|
// push a null instruction as a placeholder for future lambda instructions
|
||||||
writer.push((String)null);
|
methodWriter.push((String)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
globals.addSyntheticMethod(function);
|
globals.addSyntheticMethod(function);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -103,20 +104,20 @@ public final class ENewObj extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
writer.newInstance(MethodWriter.getType(actual));
|
methodWriter.newInstance(MethodWriter.getType(actual));
|
||||||
|
|
||||||
if (read) {
|
if (read) {
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AExpression argument : arguments) {
|
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));
|
Type.getType(constructor.javaConstructor.getDeclaringClass()), Method.getMethod(constructor.javaConstructor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -69,8 +70,8 @@ public final class ENull extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.visitInsn(Opcodes.ACONST_NULL);
|
methodWriter.visitInsn(Opcodes.ACONST_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -121,7 +122,7 @@ public final class ENumeric extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Constant;
|
import org.elasticsearch.painless.Constant;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -91,10 +92,10 @@ public final class ERegex extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
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);
|
globals.addConstantInitializer(constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -61,7 +62,7 @@ public final class EStatic extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -59,7 +60,7 @@ public final class EString extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
throw new IllegalStateException("Illegal tree structure.");
|
throw new IllegalStateException("Illegal tree structure.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.AnalyzerCaster;
|
import org.elasticsearch.painless.AnalyzerCaster;
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.DefBootstrap;
|
import org.elasticsearch.painless.DefBootstrap;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -192,23 +193,23 @@ public final class EUnary extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
if (operation == Operation.NOT) {
|
if (operation == Operation.NOT) {
|
||||||
Label fals = new Label();
|
Label fals = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
child.write(writer, globals);
|
child.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, fals);
|
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
|
||||||
|
|
||||||
writer.push(false);
|
methodWriter.push(false);
|
||||||
writer.goTo(end);
|
methodWriter.goTo(end);
|
||||||
writer.mark(fals);
|
methodWriter.mark(fals);
|
||||||
writer.push(true);
|
methodWriter.push(true);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
} else {
|
} else {
|
||||||
child.write(writer, globals);
|
child.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
// Def calls adopt the wanted return value. If there was a narrowing cast,
|
// 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.
|
// 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 (operation == Operation.BWNOT) {
|
||||||
if (promote == def.class) {
|
if (promote == def.class) {
|
||||||
org.objectweb.asm.Type descriptor = org.objectweb.asm.Type.getMethodType(actualType, childType);
|
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 {
|
} else {
|
||||||
if (promote == int.class) {
|
if (promote == int.class) {
|
||||||
writer.push(-1);
|
methodWriter.push(-1);
|
||||||
} else if (promote == long.class) {
|
} else if (promote == long.class) {
|
||||||
writer.push(-1L);
|
methodWriter.push(-1L);
|
||||||
} else {
|
} else {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.math(MethodWriter.XOR, actualType);
|
methodWriter.math(MethodWriter.XOR, actualType);
|
||||||
}
|
}
|
||||||
} else if (operation == Operation.SUB) {
|
} else if (operation == Operation.SUB) {
|
||||||
if (promote == def.class) {
|
if (promote == def.class) {
|
||||||
org.objectweb.asm.Type descriptor = org.objectweb.asm.Type.getMethodType(actualType, childType);
|
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 {
|
} else {
|
||||||
writer.math(MethodWriter.NEG, actualType);
|
methodWriter.math(MethodWriter.NEG, actualType);
|
||||||
}
|
}
|
||||||
} else if (operation == Operation.ADD) {
|
} else if (operation == Operation.ADD) {
|
||||||
if (promote == def.class) {
|
if (promote == def.class) {
|
||||||
org.objectweb.asm.Type descriptor = org.objectweb.asm.Type.getMethodType(actualType, childType);
|
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 {
|
} else {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -67,8 +68,8 @@ public final class EVariable extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ILOAD), variable.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ILOAD), variable.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -87,18 +88,18 @@ public final class EVariable extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ILOAD), variable.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ILOAD), variable.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ISTORE), variable.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(actual).getOpcode(Opcodes.ISTORE), variable.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -87,9 +88,9 @@ public final class PBrace extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
prefix.write(writer, globals);
|
prefix.write(classWriter, methodWriter, globals);
|
||||||
sub.write(writer, globals);
|
sub.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -109,19 +110,19 @@ public final class PBrace extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
prefix.write(writer, globals);
|
prefix.write(classWriter, methodWriter, globals);
|
||||||
sub.setup(writer, globals);
|
sub.setup(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
sub.load(writer, globals);
|
sub.load(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
sub.store(writer, globals);
|
sub.store(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -103,9 +104,9 @@ public final class PCallInvoke extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
prefix.write(writer, globals);
|
prefix.write(classWriter, methodWriter, globals);
|
||||||
sub.write(writer, globals);
|
sub.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -128,9 +129,9 @@ public final class PField extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
prefix.write(writer, globals);
|
prefix.write(classWriter, methodWriter, globals);
|
||||||
sub.write(writer, globals);
|
sub.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -150,19 +151,19 @@ public final class PField extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
prefix.write(writer, globals);
|
prefix.write(classWriter, methodWriter, globals);
|
||||||
sub.setup(writer, globals);
|
sub.setup(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
sub.load(writer, globals);
|
sub.load(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
sub.store(writer, globals);
|
sub.store(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -67,9 +68,9 @@ final class PSubArrayLength extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.arrayLength();
|
methodWriter.arrayLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -88,17 +89,17 @@ final class PSubArrayLength extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
throw new IllegalStateException("Illegal tree structure.");
|
throw new IllegalStateException("Illegal tree structure.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
throw new IllegalStateException("Illegal tree structure.");
|
throw new IllegalStateException("Illegal tree structure.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
throw new IllegalStateException("Illegal tree structure.");
|
throw new IllegalStateException("Illegal tree structure.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -63,9 +64,9 @@ final class PSubBrace extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
setup(writer, globals);
|
setup(classWriter, methodWriter, globals);
|
||||||
load(writer, globals);
|
load(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -84,21 +85,21 @@ final class PSubBrace extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
index.write(writer, globals);
|
index.write(classWriter, methodWriter, globals);
|
||||||
writeIndexFlip(writer, MethodWriter::arrayLength);
|
writeIndexFlip(methodWriter, MethodWriter::arrayLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.arrayLoad(MethodWriter.getType(actual));
|
methodWriter.arrayLoad(MethodWriter.getType(actual));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.arrayStore(MethodWriter.getType(actual));
|
methodWriter.arrayStore(MethodWriter.getType(actual));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -73,18 +74,18 @@ final class PSubCallInvoke extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
if (box.isPrimitive()) {
|
if (box.isPrimitive()) {
|
||||||
writer.box(MethodWriter.getType(box));
|
methodWriter.box(MethodWriter.getType(box));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AExpression argument : arguments) {
|
for (AExpression argument : arguments) {
|
||||||
argument.write(writer, globals);
|
argument.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.invokeMethodCall(method);
|
methodWriter.invokeMethodCall(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.DefBootstrap;
|
import org.elasticsearch.painless.DefBootstrap;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -65,9 +66,9 @@ final class PSubDefArray extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
setup(writer, globals);
|
setup(classWriter, methodWriter, globals);
|
||||||
load(writer, globals);
|
load(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -86,32 +87,31 @@ final class PSubDefArray extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
// Current stack: def
|
methodWriter.dup();
|
||||||
writer.dup(); // def, def
|
index.write(classWriter, methodWriter, globals);
|
||||||
index.write(writer, globals); // def, def, unnormalized_index
|
|
||||||
Type methodType = Type.getMethodType(
|
Type methodType = Type.getMethodType(
|
||||||
MethodWriter.getType(index.actual), Type.getType(Object.class), MethodWriter.getType(index.actual));
|
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
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
Type methodType =
|
Type methodType =
|
||||||
Type.getMethodType(MethodWriter.getType(actual), Type.getType(Object.class), MethodWriter.getType(index.actual));
|
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
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
Type methodType =
|
Type methodType =
|
||||||
Type.getMethodType(
|
Type.getMethodType(
|
||||||
Type.getType(void.class), Type.getType(Object.class), MethodWriter.getType(index.actual), MethodWriter.getType(actual));
|
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
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.DefBootstrap;
|
import org.elasticsearch.painless.DefBootstrap;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -96,8 +97,8 @@ final class PSubDefCall extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
List<Type> parameterTypes = new ArrayList<>();
|
List<Type> parameterTypes = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -113,7 +114,7 @@ final class PSubDefCall extends AExpression {
|
||||||
Collections.addAll(parameterTypes, lambda.getCaptures());
|
Collections.addAll(parameterTypes, lambda.getCaptures());
|
||||||
}
|
}
|
||||||
|
|
||||||
argument.write(writer, globals);
|
argument.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create method type from return value and arguments
|
// create method type from return value and arguments
|
||||||
|
@ -122,7 +123,7 @@ final class PSubDefCall extends AExpression {
|
||||||
List<Object> args = new ArrayList<>();
|
List<Object> args = new ArrayList<>();
|
||||||
args.add(recipe.toString());
|
args.add(recipe.toString());
|
||||||
args.addAll(pointers);
|
args.addAll(pointers);
|
||||||
writer.invokeDefCall(name, methodType, DefBootstrap.METHOD_CALL, args.toArray());
|
methodWriter.invokeDefCall(name, methodType, DefBootstrap.METHOD_CALL, args.toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.DefBootstrap;
|
import org.elasticsearch.painless.DefBootstrap;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -61,12 +62,12 @@ final class PSubDefField extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
org.objectweb.asm.Type methodType =
|
org.objectweb.asm.Type methodType =
|
||||||
org.objectweb.asm.Type.getMethodType(MethodWriter.getType(actual), org.objectweb.asm.Type.getType(Object.class));
|
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
|
@Override
|
||||||
|
@ -85,26 +86,26 @@ final class PSubDefField extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
org.objectweb.asm.Type methodType =
|
org.objectweb.asm.Type methodType =
|
||||||
org.objectweb.asm.Type.getMethodType(MethodWriter.getType(actual), org.objectweb.asm.Type.getType(Object.class));
|
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
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
org.objectweb.asm.Type methodType = org.objectweb.asm.Type.getMethodType(
|
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));
|
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
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -66,14 +67,14 @@ final class PSubField extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isStatic(field.javaField.getModifiers())) {
|
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));
|
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
|
||||||
} else {
|
} else {
|
||||||
writer.getField(Type.getType(
|
methodWriter.getField(Type.getType(
|
||||||
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
|
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,32 +95,32 @@ final class PSubField extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter,Globals globals) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter,Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isStatic(field.javaField.getModifiers())) {
|
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));
|
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
|
||||||
} else {
|
} else {
|
||||||
writer.getField(Type.getType(
|
methodWriter.getField(Type.getType(
|
||||||
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
|
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter,Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
if (java.lang.reflect.Modifier.isStatic(field.javaField.getModifiers())) {
|
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));
|
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
|
||||||
} else {
|
} else {
|
||||||
writer.putField(Type.getType(
|
methodWriter.putField(Type.getType(
|
||||||
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
|
field.javaField.getDeclaringClass()), field.javaField.getName(), MethodWriter.getType(field.typeParameter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -92,9 +93,9 @@ final class PSubListShortcut extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
setup(writer, globals);
|
setup(classWriter, methodWriter, globals);
|
||||||
load(writer, globals);
|
load(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,28 +114,28 @@ final class PSubListShortcut extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
index.write(writer, globals);
|
index.write(classWriter, methodWriter, globals);
|
||||||
writeIndexFlip(writer, w -> {
|
writeIndexFlip(methodWriter, w -> {
|
||||||
w.invokeInterface(WriterConstants.COLLECTION_TYPE, WriterConstants.COLLECTION_SIZE);
|
w.invokeInterface(WriterConstants.COLLECTION_TYPE, WriterConstants.COLLECTION_SIZE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.invokeMethodCall(getter);
|
methodWriter.invokeMethodCall(getter);
|
||||||
|
|
||||||
if (getter.returnType == getter.javaMethod.getReturnType()) {
|
if (getter.returnType == getter.javaMethod.getReturnType()) {
|
||||||
writer.checkCast(MethodWriter.getType(getter.returnType));
|
methodWriter.checkCast(MethodWriter.getType(getter.returnType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.invokeMethodCall(setter);
|
methodWriter.invokeMethodCall(setter);
|
||||||
writer.writePop(MethodWriter.getType(setter.returnType).getSize());
|
methodWriter.writePop(MethodWriter.getType(setter.returnType).getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -90,14 +91,14 @@ final class PSubMapShortcut extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
index.write(writer, globals);
|
index.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.invokeMethodCall(getter);
|
methodWriter.invokeMethodCall(getter);
|
||||||
|
|
||||||
if (getter.returnType != getter.javaMethod.getReturnType()) {
|
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
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
index.write(writer, globals);
|
index.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.invokeMethodCall(getter);
|
methodWriter.invokeMethodCall(getter);
|
||||||
|
|
||||||
if (getter.returnType != getter.javaMethod.getReturnType()) {
|
if (getter.returnType != getter.javaMethod.getReturnType()) {
|
||||||
writer.checkCast(MethodWriter.getType(getter.returnType));
|
methodWriter.checkCast(MethodWriter.getType(getter.returnType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
writer.invokeMethodCall(setter);
|
methodWriter.invokeMethodCall(setter);
|
||||||
writer.writePop(MethodWriter.getType(setter.returnType).getSize());
|
methodWriter.writePop(MethodWriter.getType(setter.returnType).getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -64,14 +65,14 @@ public class PSubNullSafeCallInvoke extends AExpression {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
writer.ifNull(end);
|
methodWriter.ifNull(end);
|
||||||
guarded.write(writer, globals);
|
guarded.write(classWriter, methodWriter, globals);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -79,26 +80,26 @@ public class PSubNullSafeField extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
writer.ifNull(end);
|
methodWriter.ifNull(end);
|
||||||
guarded.write(writer, globals);
|
guarded.write(classWriter, methodWriter, globals);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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"));
|
throw createError(new IllegalArgumentException("Can't write to null safe field"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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"));
|
throw createError(new IllegalArgumentException("Can't write to null safe field"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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"));
|
throw createError(new IllegalArgumentException("Can't write to null safe field"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -81,13 +82,13 @@ final class PSubShortcut extends AStoreable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
writer.invokeMethodCall(getter);
|
methodWriter.invokeMethodCall(getter);
|
||||||
|
|
||||||
if (!getter.returnType.equals(getter.javaMethod.getReturnType())) {
|
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
|
@Override
|
||||||
void setup(MethodWriter writer, Globals globals) {
|
void setup(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void load(MethodWriter writer, Globals globals) {
|
void load(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
writer.invokeMethodCall(getter);
|
methodWriter.invokeMethodCall(getter);
|
||||||
|
|
||||||
if (getter.returnType != getter.javaMethod.getReturnType()) {
|
if (getter.returnType != getter.javaMethod.getReturnType()) {
|
||||||
writer.checkCast(MethodWriter.getType(getter.returnType));
|
methodWriter.checkCast(MethodWriter.getType(getter.returnType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void store(MethodWriter writer, Globals globals) {
|
void store(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeDebugInfo(location);
|
methodWriter.writeDebugInfo(location);
|
||||||
|
|
||||||
writer.invokeMethodCall(setter);
|
methodWriter.invokeMethodCall(setter);
|
||||||
|
|
||||||
writer.writePop(MethodWriter.getType(setter.returnType).getSize());
|
methodWriter.writePop(MethodWriter.getType(setter.returnType).getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -89,11 +90,11 @@ public final class SBlock extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
for (AStatement statement : statements) {
|
for (AStatement statement : statements) {
|
||||||
statement.continu = continu;
|
statement.continu = continu;
|
||||||
statement.brake = brake;
|
statement.brake = brake;
|
||||||
statement.write(writer, globals);
|
statement.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -59,8 +60,8 @@ public final class SBreak extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.goTo(brake);
|
methodWriter.goTo(brake);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -101,24 +102,24 @@ public final class SCatch extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
Label jump = new Label();
|
Label jump = new Label();
|
||||||
|
|
||||||
writer.mark(jump);
|
methodWriter.mark(jump);
|
||||||
writer.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
|
||||||
|
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
block.continu = continu;
|
block.continu = continu;
|
||||||
block.brake = brake;
|
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)) {
|
if (exception != null && (block == null || !block.allEscape)) {
|
||||||
writer.goTo(exception);
|
methodWriter.goTo(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Constant;
|
import org.elasticsearch.painless.Constant;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -28,16 +29,13 @@ import org.elasticsearch.painless.Locals.Variable;
|
||||||
import org.elasticsearch.painless.Location;
|
import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.ScriptClassInfo;
|
import org.elasticsearch.painless.ScriptClassInfo;
|
||||||
import org.elasticsearch.painless.SimpleChecksAdapter;
|
|
||||||
import org.elasticsearch.painless.WriterConstants;
|
import org.elasticsearch.painless.WriterConstants;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookup;
|
import org.elasticsearch.painless.lookup.PainlessLookup;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.util.Printer;
|
import org.objectweb.asm.util.Printer;
|
||||||
import org.objectweb.asm.util.TraceClassVisitor;
|
|
||||||
|
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -199,30 +197,19 @@ public final class SClass extends AStatement {
|
||||||
public Map<String, Object> write() {
|
public Map<String, Object> write() {
|
||||||
// Create the ClassWriter.
|
// 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;
|
int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL;
|
||||||
String interfaceBase = BASE_INTERFACE_TYPE.getInternalName();
|
String interfaceBase = BASE_INTERFACE_TYPE.getInternalName();
|
||||||
String className = CLASS_TYPE.getInternalName();
|
String className = CLASS_TYPE.getInternalName();
|
||||||
String classInterfaces[] = new String[] { interfaceBase };
|
String[] classInterfaces = new String[] { interfaceBase };
|
||||||
|
|
||||||
ClassWriter writer = new ClassWriter(classFrames);
|
ClassWriter classWriter = new ClassWriter(settings, globals.getStatements(), debugStream,
|
||||||
ClassVisitor visitor = writer;
|
scriptClassInfo.getBaseClass(), classFrames, classAccess, className, classInterfaces);
|
||||||
|
ClassVisitor classVisitor = classWriter.getClassVisitor();
|
||||||
// if picky is enabled, turn on some checks. instead of VerifyError at the end, you get a helpful stacktrace.
|
classVisitor.visitSource(Location.computeSourceName(name), null);
|
||||||
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);
|
|
||||||
|
|
||||||
// Write the a method to bootstrap def calls
|
// Write the a method to bootstrap def calls
|
||||||
MethodWriter bootstrapDef = new MethodWriter(Opcodes.ACC_STATIC | Opcodes.ACC_VARARGS, DEF_BOOTSTRAP_METHOD, visitor,
|
MethodWriter bootstrapDef = classWriter.newMethodWriter(Opcodes.ACC_STATIC | Opcodes.ACC_VARARGS, DEF_BOOTSTRAP_METHOD);
|
||||||
globals.getStatements(), settings);
|
|
||||||
bootstrapDef.visitCode();
|
bootstrapDef.visitCode();
|
||||||
bootstrapDef.getStatic(CLASS_TYPE, "$DEFINITION", DEFINITION_TYPE);
|
bootstrapDef.getStatic(CLASS_TYPE, "$DEFINITION", DEFINITION_TYPE);
|
||||||
bootstrapDef.getStatic(CLASS_TYPE, "$LOCALS", MAP_TYPE);
|
bootstrapDef.getStatic(CLASS_TYPE, "$LOCALS", MAP_TYPE);
|
||||||
|
@ -232,13 +219,14 @@ public final class SClass extends AStatement {
|
||||||
bootstrapDef.endMethod();
|
bootstrapDef.endMethod();
|
||||||
|
|
||||||
// Write static variables for name, source and statements used for writing exception messages
|
// 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();
|
classVisitor.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();
|
classVisitor.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, "$STATEMENTS", BITSET_TYPE.getDescriptor(), null, null).visitEnd();
|
||||||
|
|
||||||
// Write the static variables used by the method to bootstrap def calls
|
// 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();
|
classVisitor.visitField(
|
||||||
visitor.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$LOCALS", MAP_TYPE.getDescriptor(), null, null).visitEnd();
|
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;
|
org.objectweb.asm.commons.Method init;
|
||||||
|
|
||||||
|
@ -250,7 +238,7 @@ public final class SClass extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the constructor:
|
// 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.visitCode();
|
||||||
constructor.loadThis();
|
constructor.loadThis();
|
||||||
constructor.loadArgs();
|
constructor.loadArgs();
|
||||||
|
@ -259,37 +247,35 @@ public final class SClass extends AStatement {
|
||||||
constructor.endMethod();
|
constructor.endMethod();
|
||||||
|
|
||||||
// Write a method to get static variable source
|
// 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.visitCode();
|
||||||
nameMethod.getStatic(CLASS_TYPE, "$NAME", STRING_TYPE);
|
nameMethod.getStatic(CLASS_TYPE, "$NAME", STRING_TYPE);
|
||||||
nameMethod.returnValue();
|
nameMethod.returnValue();
|
||||||
nameMethod.endMethod();
|
nameMethod.endMethod();
|
||||||
|
|
||||||
// Write a method to get static variable source
|
// 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.visitCode();
|
||||||
sourceMethod.getStatic(CLASS_TYPE, "$SOURCE", STRING_TYPE);
|
sourceMethod.getStatic(CLASS_TYPE, "$SOURCE", STRING_TYPE);
|
||||||
sourceMethod.returnValue();
|
sourceMethod.returnValue();
|
||||||
sourceMethod.endMethod();
|
sourceMethod.endMethod();
|
||||||
|
|
||||||
// Write a method to get static variable statements
|
// Write a method to get static variable statements
|
||||||
MethodWriter statementsMethod =
|
MethodWriter statementsMethod = classWriter.newMethodWriter(Opcodes.ACC_PUBLIC, GET_STATEMENTS_METHOD);
|
||||||
new MethodWriter(Opcodes.ACC_PUBLIC, GET_STATEMENTS_METHOD, visitor, globals.getStatements(), settings);
|
|
||||||
statementsMethod.visitCode();
|
statementsMethod.visitCode();
|
||||||
statementsMethod.getStatic(CLASS_TYPE, "$STATEMENTS", BITSET_TYPE);
|
statementsMethod.getStatic(CLASS_TYPE, "$STATEMENTS", BITSET_TYPE);
|
||||||
statementsMethod.returnValue();
|
statementsMethod.returnValue();
|
||||||
statementsMethod.endMethod();
|
statementsMethod.endMethod();
|
||||||
|
|
||||||
// Write the method defined in the interface:
|
// Write the method defined in the interface:
|
||||||
MethodWriter executeMethod = new MethodWriter(Opcodes.ACC_PUBLIC, scriptClassInfo.getExecuteMethod(), visitor,
|
MethodWriter executeMethod = classWriter.newMethodWriter(Opcodes.ACC_PUBLIC, scriptClassInfo.getExecuteMethod());
|
||||||
globals.getStatements(), settings);
|
|
||||||
executeMethod.visitCode();
|
executeMethod.visitCode();
|
||||||
write(executeMethod, globals);
|
write(classWriter, executeMethod, globals);
|
||||||
executeMethod.endMethod();
|
executeMethod.endMethod();
|
||||||
|
|
||||||
// Write all functions:
|
// Write all functions:
|
||||||
for (SFunction function : 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 :)
|
// 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());
|
List<SFunction> current = new ArrayList<>(globals.getSyntheticMethods().values());
|
||||||
globals.getSyntheticMethods().clear();
|
globals.getSyntheticMethods().clear();
|
||||||
for (SFunction function : current) {
|
for (SFunction function : current) {
|
||||||
function.write(visitor, settings, globals);
|
function.write(classWriter, globals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +293,7 @@ public final class SClass extends AStatement {
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
for (Constant constant : inits) {
|
for (Constant constant : inits) {
|
||||||
visitor.visitField(
|
classVisitor.visitField(
|
||||||
Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC,
|
Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC,
|
||||||
constant.name,
|
constant.name,
|
||||||
constant.type.getDescriptor(),
|
constant.type.getDescriptor(),
|
||||||
|
@ -317,7 +303,7 @@ public final class SClass extends AStatement {
|
||||||
|
|
||||||
// Initialize the constants in a static initializer
|
// Initialize the constants in a static initializer
|
||||||
final MethodWriter clinit = new MethodWriter(Opcodes.ACC_STATIC,
|
final MethodWriter clinit = new MethodWriter(Opcodes.ACC_STATIC,
|
||||||
WriterConstants.CLINIT, visitor, globals.getStatements(), settings);
|
WriterConstants.CLINIT, classVisitor, globals.getStatements(), settings);
|
||||||
clinit.visitCode();
|
clinit.visitCode();
|
||||||
for (Constant constant : inits) {
|
for (Constant constant : inits) {
|
||||||
constant.initializer.accept(clinit);
|
constant.initializer.accept(clinit);
|
||||||
|
@ -331,14 +317,14 @@ public final class SClass extends AStatement {
|
||||||
for (Map.Entry<String, Class<?>> classBinding : globals.getClassBindings().entrySet()) {
|
for (Map.Entry<String, Class<?>> classBinding : globals.getClassBindings().entrySet()) {
|
||||||
String name = classBinding.getKey();
|
String name = classBinding.getKey();
|
||||||
String descriptor = Type.getType(classBinding.getValue()).getDescriptor();
|
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
|
// Write instance binding variables
|
||||||
for (Map.Entry<Object, String> instanceBinding : globals.getInstanceBindings().entrySet()) {
|
for (Map.Entry<Object, String> instanceBinding : globals.getInstanceBindings().entrySet()) {
|
||||||
String name = instanceBinding.getValue();
|
String name = instanceBinding.getValue();
|
||||||
String descriptor = Type.getType(instanceBinding.getKey().getClass()).getDescriptor();
|
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
|
// Write any needsVarName methods for used variables
|
||||||
|
@ -346,7 +332,7 @@ public final class SClass extends AStatement {
|
||||||
String name = needsMethod.getName();
|
String name = needsMethod.getName();
|
||||||
name = name.substring(5);
|
name = name.substring(5);
|
||||||
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
|
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.visitCode();
|
||||||
ifaceMethod.push(extractedVariables.contains(name));
|
ifaceMethod.push(extractedVariables.contains(name));
|
||||||
ifaceMethod.returnValue();
|
ifaceMethod.returnValue();
|
||||||
|
@ -355,8 +341,8 @@ public final class SClass extends AStatement {
|
||||||
|
|
||||||
// End writing the class and store the generated bytes.
|
// End writing the class and store the generated bytes.
|
||||||
|
|
||||||
visitor.visitEnd();
|
classVisitor.visitEnd();
|
||||||
bytes = writer.toByteArray();
|
bytes = classWriter.getClassBytes();
|
||||||
|
|
||||||
Map<String, Object> statics = new HashMap<>();
|
Map<String, Object> statics = new HashMap<>();
|
||||||
statics.put("$LOCALS", mainMethod.getMethods());
|
statics.put("$LOCALS", mainMethod.getMethods());
|
||||||
|
@ -369,14 +355,14 @@ public final class SClass extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
// We wrap the whole method in a few try/catches to handle and/or convert other exceptions to ScriptException
|
||||||
Label startTry = new Label();
|
Label startTry = new Label();
|
||||||
Label endTry = new Label();
|
Label endTry = new Label();
|
||||||
Label startExplainCatch = new Label();
|
Label startExplainCatch = new Label();
|
||||||
Label startOtherCatch = new Label();
|
Label startOtherCatch = new Label();
|
||||||
Label endCatch = new Label();
|
Label endCatch = new Label();
|
||||||
writer.mark(startTry);
|
methodWriter.mark(startTry);
|
||||||
|
|
||||||
if (settings.getMaxLoopCounter() > 0) {
|
if (settings.getMaxLoopCounter() > 0) {
|
||||||
// if there is infinite loop protection, we do this once:
|
// 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);
|
Variable loop = mainMethod.getVariable(null, Locals.LOOP);
|
||||||
|
|
||||||
writer.push(settings.getMaxLoopCounter());
|
methodWriter.push(settings.getMaxLoopCounter());
|
||||||
writer.visitVarInsn(Opcodes.ISTORE, loop.getSlot());
|
methodWriter.visitVarInsn(Opcodes.ISTORE, loop.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (org.objectweb.asm.commons.Method method : getMethods) {
|
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);
|
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
|
||||||
Variable variable = mainMethod.getVariable(null, name);
|
Variable variable = mainMethod.getVariable(null, name);
|
||||||
|
|
||||||
writer.loadThis();
|
methodWriter.loadThis();
|
||||||
writer.invokeVirtual(Type.getType(scriptClassInfo.getBaseClass()), method);
|
methodWriter.invokeVirtual(Type.getType(scriptClassInfo.getBaseClass()), method);
|
||||||
writer.visitVarInsn(method.getReturnType().getOpcode(Opcodes.ISTORE), variable.getSlot());
|
methodWriter.visitVarInsn(method.getReturnType().getOpcode(Opcodes.ISTORE), variable.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AStatement statement : statements) {
|
for (AStatement statement : statements) {
|
||||||
statement.write(writer, globals);
|
statement.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
if (!methodEscape) {
|
if (!methodEscape) {
|
||||||
switch (scriptClassInfo.getExecuteMethod().getReturnType().getSort()) {
|
switch (scriptClassInfo.getExecuteMethod().getReturnType().getSort()) {
|
||||||
case org.objectweb.asm.Type.VOID:
|
case org.objectweb.asm.Type.VOID:
|
||||||
break;
|
break;
|
||||||
case org.objectweb.asm.Type.BOOLEAN:
|
case org.objectweb.asm.Type.BOOLEAN:
|
||||||
writer.push(false);
|
methodWriter.push(false);
|
||||||
break;
|
break;
|
||||||
case org.objectweb.asm.Type.BYTE:
|
case org.objectweb.asm.Type.BYTE:
|
||||||
writer.push(0);
|
methodWriter.push(0);
|
||||||
break;
|
break;
|
||||||
case org.objectweb.asm.Type.SHORT:
|
case org.objectweb.asm.Type.SHORT:
|
||||||
writer.push(0);
|
methodWriter.push(0);
|
||||||
break;
|
break;
|
||||||
case org.objectweb.asm.Type.INT:
|
case org.objectweb.asm.Type.INT:
|
||||||
writer.push(0);
|
methodWriter.push(0);
|
||||||
break;
|
break;
|
||||||
case org.objectweb.asm.Type.LONG:
|
case org.objectweb.asm.Type.LONG:
|
||||||
writer.push(0L);
|
methodWriter.push(0L);
|
||||||
break;
|
break;
|
||||||
case org.objectweb.asm.Type.FLOAT:
|
case org.objectweb.asm.Type.FLOAT:
|
||||||
writer.push(0f);
|
methodWriter.push(0f);
|
||||||
break;
|
break;
|
||||||
case org.objectweb.asm.Type.DOUBLE:
|
case org.objectweb.asm.Type.DOUBLE:
|
||||||
writer.push(0d);
|
methodWriter.push(0d);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
writer.visitInsn(Opcodes.ACONST_NULL);
|
methodWriter.visitInsn(Opcodes.ACONST_NULL);
|
||||||
}
|
}
|
||||||
writer.returnValue();
|
methodWriter.returnValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.mark(endTry);
|
methodWriter.mark(endTry);
|
||||||
writer.goTo(endCatch);
|
methodWriter.goTo(endCatch);
|
||||||
// This looks like:
|
// This looks like:
|
||||||
// } catch (PainlessExplainError e) {
|
// } catch (PainlessExplainError e) {
|
||||||
// throw this.convertToScriptException(e, e.getHeaders($DEFINITION))
|
// throw this.convertToScriptException(e, e.getHeaders($DEFINITION))
|
||||||
// }
|
// }
|
||||||
writer.visitTryCatchBlock(startTry, endTry, startExplainCatch, PAINLESS_EXPLAIN_ERROR_TYPE.getInternalName());
|
methodWriter.visitTryCatchBlock(startTry, endTry, startExplainCatch, PAINLESS_EXPLAIN_ERROR_TYPE.getInternalName());
|
||||||
writer.mark(startExplainCatch);
|
methodWriter.mark(startExplainCatch);
|
||||||
writer.loadThis();
|
methodWriter.loadThis();
|
||||||
writer.swap();
|
methodWriter.swap();
|
||||||
writer.dup();
|
methodWriter.dup();
|
||||||
writer.getStatic(CLASS_TYPE, "$DEFINITION", DEFINITION_TYPE);
|
methodWriter.getStatic(CLASS_TYPE, "$DEFINITION", DEFINITION_TYPE);
|
||||||
writer.invokeVirtual(PAINLESS_EXPLAIN_ERROR_TYPE, PAINLESS_EXPLAIN_ERROR_GET_HEADERS_METHOD);
|
methodWriter.invokeVirtual(PAINLESS_EXPLAIN_ERROR_TYPE, PAINLESS_EXPLAIN_ERROR_GET_HEADERS_METHOD);
|
||||||
writer.invokeInterface(BASE_INTERFACE_TYPE, CONVERT_TO_SCRIPT_EXCEPTION_METHOD);
|
methodWriter.invokeInterface(BASE_INTERFACE_TYPE, CONVERT_TO_SCRIPT_EXCEPTION_METHOD);
|
||||||
writer.throwException();
|
methodWriter.throwException();
|
||||||
// This looks like:
|
// This looks like:
|
||||||
// } catch (PainlessError | BootstrapMethodError | OutOfMemoryError | StackOverflowError | Exception e) {
|
// } catch (PainlessError | BootstrapMethodError | OutOfMemoryError | StackOverflowError | Exception e) {
|
||||||
// throw this.convertToScriptException(e, e.getHeaders())
|
// throw this.convertToScriptException(e, e.getHeaders())
|
||||||
// }
|
// }
|
||||||
// We *think* it is ok to catch OutOfMemoryError and StackOverflowError because Painless is stateless
|
// We *think* it is ok to catch OutOfMemoryError and StackOverflowError because Painless is stateless
|
||||||
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, PAINLESS_ERROR_TYPE.getInternalName());
|
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, PAINLESS_ERROR_TYPE.getInternalName());
|
||||||
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, BOOTSTRAP_METHOD_ERROR_TYPE.getInternalName());
|
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, BOOTSTRAP_METHOD_ERROR_TYPE.getInternalName());
|
||||||
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, OUT_OF_MEMORY_ERROR_TYPE.getInternalName());
|
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, OUT_OF_MEMORY_ERROR_TYPE.getInternalName());
|
||||||
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, STACK_OVERFLOW_ERROR_TYPE.getInternalName());
|
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, STACK_OVERFLOW_ERROR_TYPE.getInternalName());
|
||||||
writer.visitTryCatchBlock(startTry, endTry, startOtherCatch, EXCEPTION_TYPE.getInternalName());
|
methodWriter.visitTryCatchBlock(startTry, endTry, startOtherCatch, EXCEPTION_TYPE.getInternalName());
|
||||||
writer.mark(startOtherCatch);
|
methodWriter.mark(startOtherCatch);
|
||||||
writer.loadThis();
|
methodWriter.loadThis();
|
||||||
writer.swap();
|
methodWriter.swap();
|
||||||
writer.invokeStatic(COLLECTIONS_TYPE, EMPTY_MAP_METHOD);
|
methodWriter.invokeStatic(COLLECTIONS_TYPE, EMPTY_MAP_METHOD);
|
||||||
writer.invokeInterface(BASE_INTERFACE_TYPE, CONVERT_TO_SCRIPT_EXCEPTION_METHOD);
|
methodWriter.invokeInterface(BASE_INTERFACE_TYPE, CONVERT_TO_SCRIPT_EXCEPTION_METHOD);
|
||||||
writer.throwException();
|
methodWriter.throwException();
|
||||||
writer.mark(endCatch);
|
methodWriter.mark(endCatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BitSet getStatements() {
|
public BitSet getStatements() {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -62,8 +63,8 @@ public final class SContinue extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.goTo(continu);
|
methodWriter.goTo(continu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -68,9 +69,9 @@ public final class SDeclBlock extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
for (AStatement declaration : declarations) {
|
for (AStatement declaration : declarations) {
|
||||||
declaration.write(writer, globals);
|
declaration.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -83,29 +84,29 @@ public final class SDeclaration extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
if (expression == null) {
|
if (expression == null) {
|
||||||
Class<?> sort = variable.clazz;
|
Class<?> sort = variable.clazz;
|
||||||
|
|
||||||
if (sort == void.class || sort == boolean.class || sort == byte.class ||
|
if (sort == void.class || sort == boolean.class || sort == byte.class ||
|
||||||
sort == short.class || sort == char.class || sort == int.class) {
|
sort == short.class || sort == char.class || sort == int.class) {
|
||||||
writer.push(0);
|
methodWriter.push(0);
|
||||||
} else if (sort == long.class) {
|
} else if (sort == long.class) {
|
||||||
writer.push(0L);
|
methodWriter.push(0L);
|
||||||
} else if (sort == float.class) {
|
} else if (sort == float.class) {
|
||||||
writer.push(0F);
|
methodWriter.push(0F);
|
||||||
} else if (sort == double.class) {
|
} else if (sort == double.class) {
|
||||||
writer.push(0D);
|
methodWriter.push(0D);
|
||||||
} else {
|
} else {
|
||||||
writer.visitInsn(Opcodes.ACONST_NULL);
|
methodWriter.visitInsn(Opcodes.ACONST_NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -107,32 +108,32 @@ public final class SDo extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
Label start = new Label();
|
Label start = new Label();
|
||||||
Label begin = new Label();
|
Label begin = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
writer.mark(start);
|
methodWriter.mark(start);
|
||||||
|
|
||||||
block.continu = begin;
|
block.continu = begin;
|
||||||
block.brake = end;
|
block.brake = end;
|
||||||
block.write(writer, globals);
|
block.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
writer.mark(begin);
|
methodWriter.mark(begin);
|
||||||
|
|
||||||
if (!continuous) {
|
if (!continuous) {
|
||||||
condition.write(writer, globals);
|
condition.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, end);
|
methodWriter.ifZCmp(Opcodes.IFEQ, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loopCounter != null) {
|
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);
|
methodWriter.goTo(start);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -119,8 +120,8 @@ public class SEach extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
sub.write(writer, globals);
|
sub.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -76,14 +77,14 @@ public final class SExpression extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
expression.write(writer, globals);
|
expression.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
if (methodEscape) {
|
if (methodEscape) {
|
||||||
writer.returnValue();
|
methodWriter.returnValue();
|
||||||
} else {
|
} else {
|
||||||
writer.writePop(MethodWriter.getType(expression.expected).getSize());
|
methodWriter.writePop(MethodWriter.getType(expression.expected).getSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -173,27 +174,27 @@ public final class SFor extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
Label start = new Label();
|
Label start = new Label();
|
||||||
Label begin = afterthought == null ? start : new Label();
|
Label begin = afterthought == null ? start : new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
if (initializer instanceof SDeclBlock) {
|
if (initializer instanceof SDeclBlock) {
|
||||||
initializer.write(writer, globals);
|
initializer.write(classWriter, methodWriter, globals);
|
||||||
} else if (initializer instanceof AExpression) {
|
} else if (initializer instanceof AExpression) {
|
||||||
AExpression initializer = (AExpression)this.initializer;
|
AExpression initializer = (AExpression)this.initializer;
|
||||||
|
|
||||||
initializer.write(writer, globals);
|
initializer.write(classWriter, methodWriter, globals);
|
||||||
writer.writePop(MethodWriter.getType(initializer.expected).getSize());
|
methodWriter.writePop(MethodWriter.getType(initializer.expected).getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.mark(start);
|
methodWriter.mark(start);
|
||||||
|
|
||||||
if (condition != null && !continuous) {
|
if (condition != null && !continuous) {
|
||||||
condition.write(writer, globals);
|
condition.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, end);
|
methodWriter.ifZCmp(Opcodes.IFEQ, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean allEscape = false;
|
boolean allEscape = false;
|
||||||
|
@ -208,29 +209,29 @@ public final class SFor extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loopCounter != null) {
|
if (loopCounter != null) {
|
||||||
writer.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
|
methodWriter.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
block.continu = begin;
|
block.continu = begin;
|
||||||
block.brake = end;
|
block.brake = end;
|
||||||
block.write(writer, globals);
|
block.write(classWriter, methodWriter, globals);
|
||||||
} else {
|
} else {
|
||||||
if (loopCounter != null) {
|
if (loopCounter != null) {
|
||||||
writer.writeLoopCounter(loopCounter.getSlot(), 1, location);
|
methodWriter.writeLoopCounter(loopCounter.getSlot(), 1, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afterthought != null) {
|
if (afterthought != null) {
|
||||||
writer.mark(begin);
|
methodWriter.mark(begin);
|
||||||
afterthought.write(writer, globals);
|
afterthought.write(classWriter, methodWriter, globals);
|
||||||
writer.writePop(MethodWriter.getType(afterthought.expected).getSize());
|
methodWriter.writePop(MethodWriter.getType(afterthought.expected).getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afterthought != null || !allEscape) {
|
if (afterthought != null || !allEscape) {
|
||||||
writer.goTo(start);
|
methodWriter.goTo(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -28,7 +29,6 @@ import org.elasticsearch.painless.Location;
|
||||||
import org.elasticsearch.painless.MethodWriter;
|
import org.elasticsearch.painless.MethodWriter;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookup;
|
import org.elasticsearch.painless.lookup.PainlessLookup;
|
||||||
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
|
@ -146,31 +146,31 @@ public final class SFunction extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Writes the function to given ClassVisitor. */
|
/** 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;
|
int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC;
|
||||||
if (synthetic) {
|
if (synthetic) {
|
||||||
access |= Opcodes.ACC_SYNTHETIC;
|
access |= Opcodes.ACC_SYNTHETIC;
|
||||||
}
|
}
|
||||||
final MethodWriter function = new MethodWriter(access, method, writer, globals.getStatements(), settings);
|
final MethodWriter methodWriter = classWriter.newMethodWriter(access, method);
|
||||||
function.visitCode();
|
methodWriter.visitCode();
|
||||||
write(function, globals);
|
write(classWriter, methodWriter, globals);
|
||||||
function.endMethod();
|
methodWriter.endMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter function, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
if (settings.getMaxLoopCounter() > 0) {
|
if (settings.getMaxLoopCounter() > 0) {
|
||||||
// if there is infinite loop protection, we do this once:
|
// if there is infinite loop protection, we do this once:
|
||||||
// int #loop = settings.getMaxLoopCounter()
|
// int #loop = settings.getMaxLoopCounter()
|
||||||
function.push(settings.getMaxLoopCounter());
|
methodWriter.push(settings.getMaxLoopCounter());
|
||||||
function.visitVarInsn(Opcodes.ISTORE, loop.getSlot());
|
methodWriter.visitVarInsn(Opcodes.ISTORE, loop.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
block.write(function, globals);
|
block.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
if (!methodEscape) {
|
if (!methodEscape) {
|
||||||
if (returnType == void.class) {
|
if (returnType == void.class) {
|
||||||
function.returnValue();
|
methodWriter.returnValue();
|
||||||
} else {
|
} else {
|
||||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -89,19 +90,19 @@ public final class SIf extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
Label fals = new Label();
|
Label fals = new Label();
|
||||||
|
|
||||||
condition.write(writer, globals);
|
condition.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, fals);
|
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
|
||||||
|
|
||||||
ifblock.continu = continu;
|
ifblock.continu = continu;
|
||||||
ifblock.brake = brake;
|
ifblock.brake = brake;
|
||||||
ifblock.write(writer, globals);
|
ifblock.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
writer.mark(fals);
|
methodWriter.mark(fals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -119,30 +120,30 @@ public final class SIfElse extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
Label fals = new Label();
|
Label fals = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
condition.write(writer, globals);
|
condition.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, fals);
|
methodWriter.ifZCmp(Opcodes.IFEQ, fals);
|
||||||
|
|
||||||
ifblock.continu = continu;
|
ifblock.continu = continu;
|
||||||
ifblock.brake = brake;
|
ifblock.brake = brake;
|
||||||
ifblock.write(writer, globals);
|
ifblock.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
if (!ifblock.allEscape) {
|
if (!ifblock.allEscape) {
|
||||||
writer.goTo(end);
|
methodWriter.goTo(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.mark(fals);
|
methodWriter.mark(fals);
|
||||||
|
|
||||||
elseblock.continu = continu;
|
elseblock.continu = continu;
|
||||||
elseblock.brake = brake;
|
elseblock.brake = brake;
|
||||||
elseblock.write(writer, globals);
|
elseblock.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -78,14 +79,14 @@ public final class SReturn extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
expression.write(writer, globals);
|
expression.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.returnValue();
|
methodWriter.returnValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.AnalyzerCaster;
|
import org.elasticsearch.painless.AnalyzerCaster;
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -76,41 +77,41 @@ final class SSubEachArray extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
expression.write(writer, globals);
|
expression.write(classWriter, methodWriter, globals);
|
||||||
writer.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ISTORE), array.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ISTORE), array.getSlot());
|
||||||
writer.push(-1);
|
methodWriter.push(-1);
|
||||||
writer.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ISTORE), index.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ISTORE), index.getSlot());
|
||||||
|
|
||||||
Label begin = new Label();
|
Label begin = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
writer.mark(begin);
|
methodWriter.mark(begin);
|
||||||
|
|
||||||
writer.visitIincInsn(index.getSlot(), 1);
|
methodWriter.visitIincInsn(index.getSlot(), 1);
|
||||||
writer.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ILOAD), index.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ILOAD), index.getSlot());
|
||||||
writer.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ILOAD), array.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ILOAD), array.getSlot());
|
||||||
writer.arrayLength();
|
methodWriter.arrayLength();
|
||||||
writer.ifICmp(MethodWriter.GE, end);
|
methodWriter.ifICmp(MethodWriter.GE, end);
|
||||||
|
|
||||||
writer.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ILOAD), array.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(array.clazz).getOpcode(Opcodes.ILOAD), array.getSlot());
|
||||||
writer.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ILOAD), index.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(index.clazz).getOpcode(Opcodes.ILOAD), index.getSlot());
|
||||||
writer.arrayLoad(MethodWriter.getType(indexed));
|
methodWriter.arrayLoad(MethodWriter.getType(indexed));
|
||||||
writer.writeCast(cast);
|
methodWriter.writeCast(cast);
|
||||||
writer.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
|
||||||
|
|
||||||
if (loopCounter != null) {
|
if (loopCounter != null) {
|
||||||
writer.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
|
methodWriter.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
block.continu = begin;
|
block.continu = begin;
|
||||||
block.brake = end;
|
block.brake = end;
|
||||||
block.write(writer, globals);
|
block.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
writer.goTo(begin);
|
methodWriter.goTo(begin);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
import org.elasticsearch.painless.AnalyzerCaster;
|
import org.elasticsearch.painless.AnalyzerCaster;
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.DefBootstrap;
|
import org.elasticsearch.painless.DefBootstrap;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
|
@ -95,45 +96,45 @@ final class SSubEachIterable extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
expression.write(writer, globals);
|
expression.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
org.objectweb.asm.Type methodType = org.objectweb.asm.Type
|
org.objectweb.asm.Type methodType = org.objectweb.asm.Type
|
||||||
.getMethodType(org.objectweb.asm.Type.getType(Iterator.class), org.objectweb.asm.Type.getType(Object.class));
|
.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 {
|
} 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 begin = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
writer.mark(begin);
|
methodWriter.mark(begin);
|
||||||
|
|
||||||
writer.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ILOAD), iterator.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ILOAD), iterator.getSlot());
|
||||||
writer.invokeInterface(ITERATOR_TYPE, ITERATOR_HASNEXT);
|
methodWriter.invokeInterface(ITERATOR_TYPE, ITERATOR_HASNEXT);
|
||||||
writer.ifZCmp(MethodWriter.EQ, end);
|
methodWriter.ifZCmp(MethodWriter.EQ, end);
|
||||||
|
|
||||||
writer.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ILOAD), iterator.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(iterator.clazz).getOpcode(Opcodes.ILOAD), iterator.getSlot());
|
||||||
writer.invokeInterface(ITERATOR_TYPE, ITERATOR_NEXT);
|
methodWriter.invokeInterface(ITERATOR_TYPE, ITERATOR_NEXT);
|
||||||
writer.writeCast(cast);
|
methodWriter.writeCast(cast);
|
||||||
writer.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
|
methodWriter.visitVarInsn(MethodWriter.getType(variable.clazz).getOpcode(Opcodes.ISTORE), variable.getSlot());
|
||||||
|
|
||||||
if (loopCounter != null) {
|
if (loopCounter != null) {
|
||||||
writer.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
|
methodWriter.writeLoopCounter(loopCounter.getSlot(), statementCount, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
block.continu = begin;
|
block.continu = begin;
|
||||||
block.brake = end;
|
block.brake = end;
|
||||||
block.write(writer, globals);
|
block.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
writer.goTo(begin);
|
methodWriter.goTo(begin);
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -64,10 +65,10 @@ public final class SThrow extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
expression.write(writer, globals);
|
expression.write(classWriter, methodWriter, globals);
|
||||||
writer.throwException();
|
methodWriter.throwException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -108,34 +109,34 @@ public final class STry extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
Label begin = new Label();
|
Label begin = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
Label exception = new Label();
|
Label exception = new Label();
|
||||||
|
|
||||||
writer.mark(begin);
|
methodWriter.mark(begin);
|
||||||
|
|
||||||
block.continu = continu;
|
block.continu = continu;
|
||||||
block.brake = brake;
|
block.brake = brake;
|
||||||
block.write(writer, globals);
|
block.write(classWriter, methodWriter, globals);
|
||||||
|
|
||||||
if (!block.allEscape) {
|
if (!block.allEscape) {
|
||||||
writer.goTo(exception);
|
methodWriter.goTo(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
|
|
||||||
for (SCatch catc : catches) {
|
for (SCatch catc : catches) {
|
||||||
catc.begin = begin;
|
catc.begin = begin;
|
||||||
catc.end = end;
|
catc.end = end;
|
||||||
catc.exception = catches.size() > 1 ? exception : null;
|
catc.exception = catches.size() > 1 ? exception : null;
|
||||||
catc.write(writer, globals);
|
catc.write(classWriter, methodWriter, globals);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!block.allEscape || catches.size() > 1) {
|
if (!block.allEscape || catches.size() > 1) {
|
||||||
writer.mark(exception);
|
methodWriter.mark(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.painless.node;
|
package org.elasticsearch.painless.node;
|
||||||
|
|
||||||
|
import org.elasticsearch.painless.ClassWriter;
|
||||||
import org.elasticsearch.painless.CompilerSettings;
|
import org.elasticsearch.painless.CompilerSettings;
|
||||||
import org.elasticsearch.painless.Globals;
|
import org.elasticsearch.painless.Globals;
|
||||||
import org.elasticsearch.painless.Locals;
|
import org.elasticsearch.painless.Locals;
|
||||||
|
@ -110,38 +111,38 @@ public final class SWhile extends AStatement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void write(MethodWriter writer, Globals globals) {
|
void write(ClassWriter classWriter, MethodWriter methodWriter, Globals globals) {
|
||||||
writer.writeStatementOffset(location);
|
methodWriter.writeStatementOffset(location);
|
||||||
|
|
||||||
Label begin = new Label();
|
Label begin = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
writer.mark(begin);
|
methodWriter.mark(begin);
|
||||||
|
|
||||||
if (!continuous) {
|
if (!continuous) {
|
||||||
condition.write(writer, globals);
|
condition.write(classWriter, methodWriter, globals);
|
||||||
writer.ifZCmp(Opcodes.IFEQ, end);
|
methodWriter.ifZCmp(Opcodes.IFEQ, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
if (loopCounter != 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.continu = begin;
|
||||||
block.brake = end;
|
block.brake = end;
|
||||||
block.write(writer, globals);
|
block.write(classWriter, methodWriter, globals);
|
||||||
} else {
|
} else {
|
||||||
if (loopCounter != null) {
|
if (loopCounter != null) {
|
||||||
writer.writeLoopCounter(loopCounter.getSlot(), 1, location);
|
methodWriter.writeLoopCounter(loopCounter.getSlot(), 1, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block == null || !block.allEscape) {
|
if (block == null || !block.allEscape) {
|
||||||
writer.goTo(begin);
|
methodWriter.goTo(begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.mark(end);
|
methodWriter.mark(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,7 +20,7 @@ import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
esplugin {
|
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'
|
classname 'org.elasticsearch.plugin.analysis.icu.AnalysisICUPlugin'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,4 +109,25 @@ public class AzureStorageCleanupThirdPartyTests extends AbstractThirdPartyReposi
|
||||||
}));
|
}));
|
||||||
future.actionGet();
|
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":{
|
"parts":{
|
||||||
"index":{
|
"index":{
|
||||||
"type":"list",
|
"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",
|
"type":"string",
|
||||||
"description":"a short version of the Accept header, e.g. json, yaml"
|
"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":{
|
"bytes":{
|
||||||
"type":"enum",
|
"type":"enum",
|
||||||
"description":"The unit in which to display byte values",
|
"description":"The unit in which to display byte values",
|
||||||
|
@ -49,6 +54,11 @@
|
||||||
"pb"
|
"pb"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"detailed":{
|
||||||
|
"type":"boolean",
|
||||||
|
"description":"If `true`, the response includes detailed information about shard recoveries",
|
||||||
|
"default":false
|
||||||
|
},
|
||||||
"master_timeout":{
|
"master_timeout":{
|
||||||
"type":"time",
|
"type":"time",
|
||||||
"description":"Explicit operation timeout for connection to master node"
|
"description":"Explicit operation timeout for connection to master node"
|
||||||
|
@ -62,6 +72,10 @@
|
||||||
"description":"Return help information",
|
"description":"Return help information",
|
||||||
"default":false
|
"default":false
|
||||||
},
|
},
|
||||||
|
"index":{
|
||||||
|
"type":"list",
|
||||||
|
"description":"Comma-separated list or wildcard expression of index names to limit the returned information"
|
||||||
|
},
|
||||||
"s":{
|
"s":{
|
||||||
"type":"list",
|
"type":"list",
|
||||||
"description":"Comma-separated list of column names or column aliases to sort by"
|
"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