-
Notifications
You must be signed in to change notification settings - Fork 4
/
ArrayIndexReadExprNode.java
94 lines (89 loc) · 4.53 KB
/
ArrayIndexReadExprNode.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.endoflineblog.truffle.part_11.nodes.exprs.arrays;
import com.endoflineblog.truffle.part_11.exceptions.EasyScriptException;
import com.endoflineblog.truffle.part_11.nodes.exprs.EasyScriptExprNode;
import com.endoflineblog.truffle.part_11.nodes.exprs.properties.CommonReadPropertyNode;
import com.endoflineblog.truffle.part_11.runtime.EasyScriptTruffleStrings;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.strings.TruffleString;
/**
* The Node representing reading array indexes
* (like {@code a[1]}).
* Similar to the class with the same name from part 10,
* the difference is we add extra specializations for when strings are used as the index,
* in code like {@code a["b"]} (which, in JavaScript, is equivalent to {@code a.b}).
*
* @see #readTruffleStringPropertyCached
* @see #readTruffleStringPropertyUncached
*/
@NodeChild("arrayExpr")
@NodeChild("indexExpr")
@ImportStatic(EasyScriptTruffleStrings.class)
public abstract class ArrayIndexReadExprNode extends EasyScriptExprNode {
/**
* A specialization for reading an integer index of an array,
* in code like {@code [1, 2][1]}.
*/
@Specialization(guards = "arrayInteropLibrary.isArrayElementReadable(array, index)", limit = "2")
protected Object readIntIndexOfArray(
Object array, int index,
@CachedLibrary("array") InteropLibrary arrayInteropLibrary) {
try {
return arrayInteropLibrary.readArrayElement(array, index);
} catch (UnsupportedMessageException | InvalidArrayIndexException e) {
throw new EasyScriptException(this, e.getMessage());
}
}
/**
* A specialization for reading a string property of an object,
* in code like {@code [1, 2]['length']}, or {@code "a"['length']}.
* This is the cached variant of the specialization,
* where the result of converting the {@link TruffleString}
* representing the property name to a Java String is saved,
* for a maximum of two different names.
* If the given indexed property access sees more than two different names,
* then we switch to the uncached variant,
* {@link #readTruffleStringPropertyUncached}.
*/
@Specialization(guards = "equals(propertyName, cachedPropertyName, equalNode)", limit = "2")
protected Object readTruffleStringPropertyCached(
Object target, @SuppressWarnings("unused") TruffleString propertyName,
@Cached @SuppressWarnings("unused") TruffleString.EqualNode equalNode,
@Cached("propertyName") @SuppressWarnings("unused") TruffleString cachedPropertyName,
@Cached @SuppressWarnings("unused") TruffleString.ToJavaStringNode toJavaStringNode,
@Cached("toJavaStringNode.execute(cachedPropertyName)") String javaStringPropertyName,
@Cached CommonReadPropertyNode commonReadPropertyNode) {
return commonReadPropertyNode.executeReadProperty(target, javaStringPropertyName);
}
/**
* A specialization for reading a string property of an object,
* in code like {@code [1, 2]['length']}, or {@code "a"['length']}.
* This is the uncached variant of the {@link #readTruffleStringPropertyCached}
* specialization, used when this indexed property access sees more than two different property names.
*/
@Specialization(replaces = "readTruffleStringPropertyCached")
protected Object readTruffleStringPropertyUncached(
Object target, TruffleString propertyName,
@Cached TruffleString.ToJavaStringNode toJavaStringNode,
@Cached CommonReadPropertyNode commonReadPropertyNode) {
return commonReadPropertyNode.executeReadProperty(target,
toJavaStringNode.execute(propertyName));
}
/**
* A specialization for reading a non-string property of an object,
* in code like {@code "a"[0]}, or {@code [1, 2][undefined]}.
*/
@Fallback
protected Object readNonTruffleStringPropertyOfObject(
Object target, Object index,
@Cached CommonReadPropertyNode commonReadPropertyNode) {
return commonReadPropertyNode.executeReadProperty(target, index);
}
}