Skip to content

Commit ac77cd3

Browse files
committed
Use cached nodes for BigInt/Number-TruffleString conversion.
1 parent 29b05e5 commit ac77cd3

File tree

5 files changed

+67
-66
lines changed

5 files changed

+67
-66
lines changed

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/BigIntPrototypeBuiltins.java

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
*/
4141
package com.oracle.truffle.js.builtins;
4242

43-
import com.oracle.truffle.api.CompilerDirectives;
4443
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4544
import com.oracle.truffle.api.dsl.Cached;
4645
import com.oracle.truffle.api.dsl.Cached.Shared;
@@ -113,58 +112,43 @@ protected Object createNode(JSContext context, JSBuiltin builtin, boolean constr
113112
return null;
114113
}
115114

116-
public abstract static class JSBigIntOperation extends JSBuiltinNode {
117-
118-
@Child private JSToIntegerAsIntNode toIntegerNode;
119-
120-
public JSBigIntOperation(JSContext context, JSBuiltin builtin) {
121-
super(context, builtin);
122-
}
123-
124-
@TruffleBoundary
125-
protected JSException noBigIntFailure(Object value) {
126-
throw Errors.createTypeError(JSRuntime.safeToString(value) + " is not a BigInt");
127-
}
128-
129-
protected int toIntegerAsInt(Object target) {
130-
if (toIntegerNode == null) {
131-
CompilerDirectives.transferToInterpreterAndInvalidate();
132-
toIntegerNode = insert(JSToIntegerAsIntNode.create());
133-
}
134-
return toIntegerNode.executeInt(target);
135-
}
115+
@TruffleBoundary
116+
static JSException noBigIntFailure(Object value) {
117+
throw Errors.createTypeError(JSRuntime.safeToString(value) + " is not a BigInt");
136118
}
137119

138-
public abstract static class JSBigIntToStringNode extends JSBigIntOperation {
120+
public abstract static class JSBigIntToStringNode extends JSBuiltinNode {
139121

140122
public JSBigIntToStringNode(JSContext context, JSBuiltin builtin) {
141123
super(context, builtin);
142124
}
143125

144-
@SuppressWarnings("unused")
145126
@Specialization(guards = {"isUndefined(radix)"})
146-
protected TruffleString toStringBigIntRadix10(BigInt thisObj, Object radix,
147-
@Cached @Shared InlinedBranchProfile radixErrorBranch) {
148-
return toStringImpl(thisObj, 10, radixErrorBranch);
127+
protected TruffleString toStringBigIntRadix10(BigInt thisObj, @SuppressWarnings("unused") Object radix,
128+
@Cached @Shared TruffleString.FromJavaStringNode fromJavaString) {
129+
return Strings.fromBigInt(fromJavaString, thisObj, 10);
149130
}
150131

151132
@Specialization(guards = {"!isUndefined(radix)"})
152133
protected TruffleString toStringBigInt(BigInt thisObj, Object radix,
134+
@Cached @Shared TruffleString.FromJavaStringNode fromJavaString,
135+
@Cached @Shared JSToIntegerAsIntNode toInteger,
153136
@Cached @Shared InlinedBranchProfile radixErrorBranch) {
154-
return toStringImpl(thisObj, radix, radixErrorBranch);
137+
return toStringImpl(thisObj, radix, fromJavaString, toInteger, radixErrorBranch);
155138
}
156139

157-
@SuppressWarnings("unused")
158140
@Specialization(guards = {"isUndefined(radix)"})
159-
protected TruffleString toStringRadix10(JSBigIntObject thisObj, Object radix,
160-
@Cached @Shared InlinedBranchProfile radixErrorBranch) {
161-
return toStringImpl(JSBigInt.valueOf(thisObj), 10, radixErrorBranch);
141+
protected TruffleString toStringRadix10(JSBigIntObject thisObj, @SuppressWarnings("unused") Object radix,
142+
@Cached @Shared TruffleString.FromJavaStringNode fromJavaString) {
143+
return Strings.fromBigInt(fromJavaString, JSBigInt.valueOf(thisObj), 10);
162144
}
163145

164146
@Specialization(guards = {"!isUndefined(radix)"})
165147
protected TruffleString toString(JSBigIntObject thisObj, Object radix,
148+
@Cached @Shared TruffleString.FromJavaStringNode fromJavaString,
149+
@Cached @Shared JSToIntegerAsIntNode toInteger,
166150
@Cached @Shared InlinedBranchProfile radixErrorBranch) {
167-
return toStringImpl(JSBigInt.valueOf(thisObj), radix, radixErrorBranch);
151+
return toStringImpl(JSBigInt.valueOf(thisObj), radix, fromJavaString, toInteger, radixErrorBranch);
168152
}
169153

170154
@SuppressWarnings("unused")
@@ -173,17 +157,20 @@ protected void toStringNoBigInt(Object thisObj, Object radix) {
173157
throw Errors.createTypeError("BigInt.prototype.toString requires that 'this' be a BigInt");
174158
}
175159

176-
private TruffleString toStringImpl(BigInt numberVal, Object radix, InlinedBranchProfile radixErrorBranch) {
177-
int radixVal = toIntegerAsInt(radix);
160+
private TruffleString toStringImpl(BigInt numberVal, Object radix,
161+
TruffleString.FromJavaStringNode fromJavaString,
162+
JSToIntegerAsIntNode toIntegerAsInt,
163+
InlinedBranchProfile radixErrorBranch) {
164+
int radixVal = toIntegerAsInt.executeInt(radix);
178165
if (radixVal < 2 || radixVal > 36) {
179166
radixErrorBranch.enter(this);
180167
throw Errors.createRangeError("toString() expects radix in range 2-36");
181168
}
182-
return Strings.fromBigInt(numberVal, radixVal);
169+
return Strings.fromBigInt(fromJavaString, numberVal, radixVal);
183170
}
184171
}
185172

186-
public abstract static class JSBigIntToLocaleStringIntlNode extends JSBigIntOperation {
173+
public abstract static class JSBigIntToLocaleStringIntlNode extends JSBuiltinNode {
187174

188175
@Child InitializeNumberFormatNode initNumberFormatNode;
189176

@@ -219,24 +206,22 @@ protected Object failForNonBigInts(Object notANumber, Object locales, Object opt
219206

220207
}
221208

222-
public abstract static class JSBigIntToLocaleStringNode extends JSBigIntOperation {
209+
public abstract static class JSBigIntToLocaleStringNode extends JSBuiltinNode {
223210

224211
public JSBigIntToLocaleStringNode(JSContext context, JSBuiltin builtin) {
225212
super(context, builtin);
226213
}
227214

228215
@Specialization
229-
protected TruffleString toLocaleStringBigInt(BigInt thisObj) {
230-
return toLocaleStringImpl(thisObj);
216+
protected TruffleString toLocaleStringBigInt(BigInt thisObj,
217+
@Cached @Shared TruffleString.FromJavaStringNode fromJavaString) {
218+
return Strings.fromBigInt(fromJavaString, thisObj);
231219
}
232220

233221
@Specialization
234-
protected TruffleString toLocaleStringJSBigInt(JSBigIntObject thisObj) {
235-
return toLocaleStringImpl(JSBigInt.valueOf(thisObj));
236-
}
237-
238-
private static TruffleString toLocaleStringImpl(BigInt bi) {
239-
return Strings.fromBigInt(bi);
222+
protected TruffleString toLocaleStringJSBigInt(JSBigIntObject thisObj,
223+
@Cached @Shared TruffleString.FromJavaStringNode fromJavaString) {
224+
return Strings.fromBigInt(fromJavaString, JSBigInt.valueOf(thisObj));
240225
}
241226

242227
@Fallback
@@ -245,7 +230,7 @@ protected Object failForNonBigInts(Object thisObject) {
245230
}
246231
}
247232

248-
public abstract static class JSBigIntValueOfNode extends JSBigIntOperation {
233+
public abstract static class JSBigIntValueOfNode extends JSBuiltinNode {
249234

250235
public JSBigIntValueOfNode(JSContext context, JSBuiltin builtin) {
251236
super(context, builtin);

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/NumberPrototypeBuiltins.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ public JSNumberToStringNode(JSContext context, JSBuiltin builtin) {
180180
super(context, builtin);
181181
}
182182

183-
protected boolean isRadix10(Object radix) {
183+
protected static boolean isRadix10(Object radix) {
184184
return radix == Undefined.instance || (radix instanceof Integer && ((Integer) radix) == 10);
185185
}
186186

@@ -193,9 +193,10 @@ protected static boolean isJSNumberInteger(JSNumberObject thisObj) {
193193

194194
@SuppressWarnings("unused")
195195
@Specialization(guards = {"isJSNumberInteger(thisObj)", "isRadix10(radix)"})
196-
protected Object toStringIntRadix10(JSNumberObject thisObj, Object radix) {
197-
Integer i = (Integer) thisObj.getNumber();
198-
return Strings.fromInt(i.intValue());
196+
protected Object toStringIntRadix10(JSNumberObject thisObj, Object radix,
197+
@Shared @Cached TruffleString.FromLongNode fromLong) {
198+
int i = (int) thisObj.getNumber();
199+
return Strings.fromLong(fromLong, i);
199200
}
200201

201202
@SuppressWarnings("unused")
@@ -217,8 +218,9 @@ protected Object toString(JSNumberObject thisObj, Object radix,
217218

218219
@SuppressWarnings("unused")
219220
@Specialization(guards = {"isRadix10(radix)"})
220-
protected Object toStringPrimitiveIntRadix10(int thisInteger, Object radix) {
221-
return Strings.fromInt(thisInteger);
221+
protected Object toStringPrimitiveIntRadix10(int thisInteger, Object radix,
222+
@Shared @Cached TruffleString.FromLongNode fromLong) {
223+
return Strings.fromLong(fromLong, thisInteger);
222224
}
223225

224226
@SuppressWarnings("unused")
@@ -260,10 +262,10 @@ protected Object toStringForeignObject(Object thisObj, Object radix,
260262
@Bind Node node,
261263
@Shared @Cached JSToIntegerAsIntNode toIntegerNode,
262264
@Shared @Cached JSDoubleToStringNode doubleToString,
265+
@Shared @Cached TruffleString.FromLongNode fromLong,
263266
@Shared @Cached InlinedBranchProfile radixOtherBranch,
264267
@Shared @Cached InlinedBranchProfile radixErrorBranch,
265-
@Cached ForeignGetDoubleValueNode getDoubleValue,
266-
@Cached TruffleString.FromLongNode fromLong) {
268+
@Cached ForeignGetDoubleValueNode getDoubleValue) {
267269
Object radixToUse;
268270
if (radix == Undefined.instance) {
269271
if (thisObj instanceof Long longValue) {
@@ -321,8 +323,9 @@ protected static Object doNumberObject(JSNumberObject thisObj) {
321323
}
322324

323325
@Specialization
324-
protected static Object doInt(int thisInteger) {
325-
return Strings.fromInt(thisInteger);
326+
protected static Object doInt(int thisInteger,
327+
@Cached TruffleString.FromLongNode fromLong) {
328+
return Strings.fromLong(fromLong, thisInteger);
326329
}
327330

328331
@Specialization(guards = "isNumber.execute(node, thisNumber)", limit = "1")

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/cast/JSToBigIntNode.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,10 @@ protected static BigInt doSymbolNullOrUndefined(Node node, Object value) {
129129
}
130130

131131
@Specialization
132-
protected static BigInt doString(Node node, TruffleString value) {
132+
protected static BigInt doString(Node node, TruffleString value,
133+
@Cached TruffleString.ToJavaStringNode toJavaString) {
133134
try {
134-
return Strings.parseBigInt(value);
135+
return Strings.parseBigInt(toJavaString, value);
135136
} catch (NumberFormatException e) {
136137
throw Errors.createErrorCannotConvertToBigInt(JSErrorType.SyntaxError, value, node);
137138
}
@@ -195,8 +196,9 @@ protected static BigInt doSymbolNullOrUndefined(Node node, Object value) {
195196
}
196197

197198
@Specialization
198-
protected static BigInt doString(Node node, TruffleString value) {
199-
return JSPrimitiveToBigIntNode.doString(node, value);
199+
protected static BigInt doString(Node node, TruffleString value,
200+
@Cached TruffleString.ToJavaStringNode toJavaString) {
201+
return JSPrimitiveToBigIntNode.doString(node, value, toJavaString);
200202
}
201203
}
202204
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/cast/JSToStringNode.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,9 @@ protected TruffleString doInteger(int value,
133133
}
134134

135135
@Specialization
136-
protected TruffleString doBigInt(BigInt value) {
137-
return Strings.fromBigInt(value);
136+
protected TruffleString doBigInt(BigInt value,
137+
@Cached TruffleString.FromJavaStringNode fromJavaString) {
138+
return Strings.fromBigInt(fromJavaString, value);
138139
}
139140

140141
@InliningCutoff

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/runtime/Strings.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -870,12 +870,17 @@ public static TruffleString fromNumber(Number number) {
870870
throw CompilerDirectives.shouldNotReachHere();
871871
}
872872

873+
@TruffleBoundary
873874
public static TruffleString fromBigInt(BigInt bi) {
874-
return fromJavaString(bi.toString());
875+
return fromBigInt(TruffleString.FromJavaStringNode.getUncached(), bi);
876+
}
877+
878+
public static TruffleString fromBigInt(TruffleString.FromJavaStringNode fromJavaStringNode, BigInt bi) {
879+
return fromJavaString(fromJavaStringNode, bi.toString());
875880
}
876881

877-
public static TruffleString fromBigInt(BigInt bi, int radix) {
878-
return fromJavaString(bi.toString(radix));
882+
public static TruffleString fromBigInt(TruffleString.FromJavaStringNode fromJavaStringNode, BigInt bi, int radix) {
883+
return fromJavaString(fromJavaStringNode, bi.toString(radix));
879884
}
880885

881886
@TruffleBoundary
@@ -927,8 +932,13 @@ public static TruffleString interopAsTruffleString(Object key, InteropLibrary st
927932
return switchEncodingNode.execute(truffleString, TruffleString.Encoding.UTF_16);
928933
}
929934

935+
@TruffleBoundary
930936
public static BigInt parseBigInt(TruffleString s) {
931-
return BigInt.valueOf(toJavaString(s));
937+
return parseBigInt(TruffleString.ToJavaStringNode.getUncached(), s);
938+
}
939+
940+
public static BigInt parseBigInt(TruffleString.ToJavaStringNode toJavaString, TruffleString s) {
941+
return BigInt.valueOf(toJavaString(toJavaString, s));
932942
}
933943

934944
public static BigInteger parseBigInteger(TruffleString s, int radix) {

0 commit comments

Comments
 (0)