Skip to content

Commit 1368dff

Browse files
committed
[GR-61789] Avoid language lookups when we already have context
PullRequest: graalpython/3674
2 parents 8597ce1 + a37c2d4 commit 1368dff

File tree

76 files changed

+506
-395
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+506
-395
lines changed

graalpython/com.oracle.graal.python.cext/src/abstract.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2024, Oracle and/or its affiliates.
1+
/* Copyright (c) 2024, 2025, Oracle and/or its affiliates.
22
* Copyright (C) 1996-2024 Python Software Foundation
33
*
44
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
@@ -2344,7 +2344,6 @@ PyMapping_GetItemString(PyObject *o, const char *key)
23442344
return GraalPyTruffleObject_GetItemString(o, key);
23452345
}
23462346

2347-
#if 0 // GraalPy change
23482347
int
23492348
PyMapping_SetItemString(PyObject *o, const char *key, PyObject *value)
23502349
{
@@ -2392,6 +2391,7 @@ PyMapping_HasKey(PyObject *o, PyObject *key)
23922391
return 0;
23932392
}
23942393

2394+
#if 0 // GraalPy change
23952395
/* This function is quite similar to PySequence_Fast(), but specialized to be
23962396
a helper for PyMapping_Keys(), PyMapping_Items() and PyMapping_Values().
23972397
*/

graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/builtin/modules/ConversionNodeTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ public class ConversionNodeTests {
6464
static final Signature SIGNATURE = new Signature(-1, false, -1, false, tsArray("arg"), null);
6565

6666
protected static Object call(Object arg, ArgumentCastNode castNode) {
67-
PythonLanguage language = PythonLanguage.get(castNode);
6867
final PythonContext pythonContext = PythonContext.get(castNode);
68+
PythonLanguage language = pythonContext.getLanguage(castNode);
6969

7070
RootCallTarget callTarget = new PRootNode(language) {
7171
@Child private CalleeContext calleeContext = CalleeContext.create();

graalpython/com.oracle.graal.python.test/src/runner.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -744,17 +744,19 @@ def run_in_subprocess_and_watch(self):
744744
]
745745
if self.runner.failfast:
746746
cmd.append('--failfast')
747-
self.process = subprocess.Popen(cmd, stdout=self.out_file, stderr=self.out_file)
748747

749-
server.settimeout(180.0)
748+
self.process = None
750749
try:
750+
self.process = subprocess.Popen(cmd, stdout=self.out_file, stderr=self.out_file)
751+
server.settimeout(180.0)
751752
sock = server.accept()[0]
752-
except TimeoutError:
753-
interrupt_process(self.process)
753+
except (TimeoutError, OSError):
754+
if self.process:
755+
interrupt_process(self.process)
754756
retries -= 1
755757
if retries:
756758
continue
757-
sys.exit("Worker failed to connect to runner multiple times")
759+
sys.exit("Worker failed to start/connect to runner multiple times")
758760

759761
with sock:
760762
conn = Connection(sock)

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_abstract.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -1476,6 +1476,49 @@ def _reference_delslice(args):
14761476
cmpfunc=unhandled_error_compare
14771477
)
14781478

1479+
test_PyMapping_SetItemString = CPyExtFunction(
1480+
_reference_setitem,
1481+
lambda: (
1482+
({'a': 1}, 'a', 2),
1483+
),
1484+
code=''' PyObject* wrap_PyMapping_SetItemString(PyObject* mapping, char* key, PyObject* value) {
1485+
if (PyMapping_SetItemString(mapping, key, value) < 0) {
1486+
return NULL;
1487+
}
1488+
return mapping;
1489+
}
1490+
''',
1491+
resultspec="O",
1492+
argspec='OsO',
1493+
arguments=["PyObject* mapping", "char* key", "PyObject* value"],
1494+
callfunction="wrap_PyMapping_SetItemString",
1495+
cmpfunc=unhandled_error_compare
1496+
)
1497+
1498+
test_PyMapping_HasKey = CPyExtFunction(
1499+
lambda args: int(args[1] in args[0]),
1500+
lambda: (
1501+
({'a': 1}, 'a'),
1502+
({'a': 1}, 'b'),
1503+
),
1504+
resultspec="i",
1505+
argspec='OO',
1506+
arguments=["PyObject* mapping", "PyObject* key"],
1507+
cmpfunc=unhandled_error_compare
1508+
)
1509+
1510+
test_PyMapping_HasKeyString = CPyExtFunction(
1511+
lambda args: int(args[1] in args[0]),
1512+
lambda: (
1513+
({'a': 1}, 'a'),
1514+
({'a': 1}, 'b'),
1515+
),
1516+
resultspec="i",
1517+
argspec='Os',
1518+
arguments=["PyObject* mapping", "char* keyStr"],
1519+
cmpfunc=unhandled_error_compare
1520+
)
1521+
14791522
test_PyMapping_Check = CPyExtFunction(
14801523
_reference_mapping_check,
14811524
_size_and_check_args,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2024, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2025, Oracle and/or its affiliates.
33
* Copyright (c) 2015, Regents of the University of California
44
*
55
* All rights reserved.
@@ -124,6 +124,7 @@
124124
import com.oracle.truffle.api.TruffleLanguage;
125125
import com.oracle.truffle.api.TruffleLogger;
126126
import com.oracle.truffle.api.debug.DebuggerTags;
127+
import com.oracle.truffle.api.dsl.Bind;
127128
import com.oracle.truffle.api.dsl.Idempotent;
128129
import com.oracle.truffle.api.frame.VirtualFrame;
129130
import com.oracle.truffle.api.instrumentation.ProvidedTags;
@@ -172,6 +173,7 @@
172173
StandardTags.WriteVariableTag.class,
173174
DebuggerTags.AlwaysHalt.class
174175
})
176+
@Bind.DefaultExpression("get($node)")
175177
public final class PythonLanguage extends TruffleLanguage<PythonContext> {
176178
public static final String J_GRAALPYTHON_ID = "graalpy";
177179
public static final TruffleString T_GRAALPYTHON_ID = tsLiteral(J_GRAALPYTHON_ID);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@
395395
import com.oracle.truffle.api.TruffleFile;
396396
import com.oracle.truffle.api.TruffleLanguage.Env;
397397
import com.oracle.truffle.api.TruffleLogger;
398+
import com.oracle.truffle.api.nodes.Node;
398399
import com.oracle.truffle.api.source.Source;
399400
import com.oracle.truffle.api.strings.TruffleString;
400401

@@ -890,10 +891,28 @@ public final PythonContext getContext() {
890891
return (PythonContext) this;
891892
}
892893

894+
/**
895+
* Return the language corresponding to this context. In runtime compiled code, prefer
896+
* {@link #getLanguage(Node)}.
897+
*/
893898
public final PythonLanguage getLanguage() {
894899
return language;
895900
}
896901

902+
/**
903+
* Return the language corresponding to this context.
904+
*
905+
* @param node And adopted node that can make the lookup fold in compiled code in even in
906+
* multi-context mode. Can be null.
907+
*/
908+
public final PythonLanguage getLanguage(Node node) {
909+
if (CompilerDirectives.inCompiledCode() && node != null && CompilerDirectives.isPartialEvaluationConstant(node) && node.getRootNode() != null) {
910+
// This will make it PE-constant in multi-context mode
911+
return PythonLanguage.get(node);
912+
}
913+
return language;
914+
}
915+
897916
/**
898917
* Checks whether the core is initialized.
899918
*/

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AsyncioModuleBuiltins.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -69,6 +69,7 @@
6969
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
7070
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
7171
import com.oracle.graal.python.nodes.statement.AbstractImportNode;
72+
import com.oracle.graal.python.runtime.PythonContext;
7273
import com.oracle.graal.python.runtime.object.PythonObjectSlowPathFactory;
7374
import com.oracle.graal.python.util.PythonUtils;
7475
import com.oracle.truffle.api.dsl.Bind;
@@ -92,9 +93,11 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
9293
@GenerateNodeFactory
9394
public abstract static class GetRunningLoop extends PythonBuiltinNode {
9495
@Specialization
95-
public Object getCurrentLoop(
96+
static Object getCurrentLoop(
97+
@Bind("this") Node inliningTarget,
98+
@Bind PythonContext context,
9699
@Cached PRaiseNode raise) {
97-
Object eventLoop = getContext().getThreadState(getLanguage()).getRunningEventLoop();
100+
Object eventLoop = context.getThreadState(context.getLanguage(inliningTarget)).getRunningEventLoop();
98101
if (eventLoop == null) {
99102
throw raise.raise(PythonBuiltinClassType.RuntimeError, ErrorMessages.NO_RUNNING_EVENT_LOOP);
100103
} else {
@@ -107,8 +110,10 @@ public Object getCurrentLoop(
107110
@GenerateNodeFactory
108111
public abstract static class InternalGetRunningLoop extends PythonBuiltinNode {
109112
@Specialization
110-
public Object getCurrentLoop() {
111-
Object eventLoop = getContext().getThreadState(getLanguage()).getRunningEventLoop();
113+
static Object getCurrentLoop(
114+
@Bind("this") Node inliningTarget,
115+
@Bind PythonContext context) {
116+
Object eventLoop = context.getThreadState(context.getLanguage(inliningTarget)).getRunningEventLoop();
112117

113118
return eventLoop == null ? PNone.NONE : eventLoop;
114119
}
@@ -118,8 +123,10 @@ public Object getCurrentLoop() {
118123
@GenerateNodeFactory
119124
public abstract static class InternalSetRunningLoop extends PythonUnaryBuiltinNode {
120125
@Specialization
121-
public Object setCurrentLoop(Object loop) {
122-
getContext().getThreadState(getLanguage()).setRunningEventLoop(loop == PNone.NONE ? null : loop);
126+
static Object setCurrentLoop(Object loop,
127+
@Bind("this") Node inliningTarget,
128+
@Bind PythonContext context) {
129+
context.getThreadState(context.getLanguage(inliningTarget)).setRunningEventLoop(loop == PNone.NONE ? null : loop);
123130
return PNone.NONE;
124131
}
125132
}
@@ -134,15 +141,17 @@ public Object setCurrentLoop(Object loop) {
134141
public abstract static class GetEventLoop extends PythonUnaryBuiltinNode {
135142

136143
@Specialization
137-
public Object getCurrentLoop(VirtualFrame frame, Object ignored,
144+
static Object getCurrentLoop(VirtualFrame frame, Object ignored,
145+
@Bind("this") Node inliningTarget,
146+
@Bind PythonContext context,
138147
@Cached CallNode callGetPolicy,
139148
@Cached CallNode callGetLoop,
140149
@Cached AbstractImportNode.ImportName importName,
141150
@Cached(parameters = "T_GET_EVENT_LOOP") GetAttributeNode.GetFixedAttributeNode getGetLoop,
142151
@Cached(parameters = "T_GET_EVENT_LOOP_POLICY") GetAttributeNode.GetFixedAttributeNode getGetLoopPolicy) {
143-
Object eventLoop = getContext().getThreadState(getLanguage()).getRunningEventLoop();
152+
Object eventLoop = context.getThreadState(context.getLanguage(inliningTarget)).getRunningEventLoop();
144153
if (eventLoop == null) {
145-
Object asyncio = importName.execute(frame, getContext(), getContext().getBuiltins(), T_ASYNCIO_EVENTS, PNone.NONE, PythonUtils.EMPTY_TRUFFLESTRING_ARRAY, 0);
154+
Object asyncio = importName.execute(frame, context, context.getBuiltins(), T_ASYNCIO_EVENTS, PNone.NONE, PythonUtils.EMPTY_TRUFFLESTRING_ARRAY, 0);
146155
Object asyncioGetPolicy = getGetLoopPolicy.execute(frame, asyncio);
147156
Object policy = callGetPolicy.execute(frame, asyncioGetPolicy);
148157
Object getLoop = getGetLoop.execute(frame, policy);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AtexitModuleBuiltins.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -132,9 +132,10 @@ private static void handleException(PythonContext context, PException e) {
132132

133133
@TruffleBoundary
134134
@Specialization
135-
Object register(Object callable, Object[] arguments, PKeyword[] keywords) {
136-
RootCallTarget callTarget = getLanguage().createCachedCallTarget(AtExitRootNode::new, AtExitRootNode.class);
137-
getContext().registerAtexitHook(callable, arguments, keywords, callTarget);
135+
static Object register(Object callable, Object[] arguments, PKeyword[] keywords) {
136+
PythonContext context = PythonContext.get(null);
137+
RootCallTarget callTarget = context.getLanguage().createCachedCallTarget(AtExitRootNode::new, AtExitRootNode.class);
138+
context.registerAtexitHook(callable, arguments, keywords, callTarget);
138139
return callable;
139140
}
140141
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -75,6 +75,7 @@
7575
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
7676
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
7777
import com.oracle.graal.python.runtime.IndirectCallData;
78+
import com.oracle.graal.python.runtime.PythonContext;
7879
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
7980
import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage;
8081
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
@@ -106,10 +107,12 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
106107

107108
abstract static class AsciiBufferConverter extends ArgumentCastNode {
108109
@Specialization(guards = "acquireLib.hasBuffer(value)", limit = "getCallSiteInlineCacheMaxDepth()")
109-
Object doObject(VirtualFrame frame, Object value,
110+
static Object doObject(VirtualFrame frame, Object value,
111+
@Bind("this") Node inliningTarget,
112+
@Bind PythonContext context,
110113
@Cached("createFor(this)") IndirectCallData indirectCallData,
111114
@CachedLibrary("value") PythonBufferAcquireLibrary acquireLib) {
112-
return acquireLib.acquireReadonly(value, frame, getContext(), getLanguage(), indirectCallData);
115+
return acquireLib.acquireReadonly(value, frame, context, context.getLanguage(inliningTarget), indirectCallData);
113116
}
114117

115118
@ExportLibrary(PythonBufferAccessLibrary.class)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,7 @@ Object compile(TruffleString expression, TruffleString filename, TruffleString m
10731073
}
10741074
if ((flags & PyCF_ONLY_AST) != 0) {
10751075
Source source = PythonLanguage.newSource(context, code, filename, mayBeFromFile, PythonLanguage.MIME_TYPE);
1076-
RaisePythonExceptionErrorCallback errorCb = new RaisePythonExceptionErrorCallback(source, PythonOptions.isPExceptionWithJavaStacktrace(getLanguage()));
1076+
RaisePythonExceptionErrorCallback errorCb = new RaisePythonExceptionErrorCallback(source, PythonOptions.isPExceptionWithJavaStacktrace(context.getLanguage()));
10771077

10781078
EnumSet<AbstractParser.Flags> compilerFlags = EnumSet.noneOf(AbstractParser.Flags.class);
10791079
if ((flags & PyCF_TYPE_COMMENTS) != 0) {
@@ -1117,6 +1117,7 @@ Object compile(TruffleString expression, TruffleString filename, TruffleString m
11171117
Object generic(VirtualFrame frame, Object wSource, Object wFilename, TruffleString mode, int flags, @SuppressWarnings("unused") boolean dontInherit, int optimize, int featureVersion,
11181118
@CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib,
11191119
@CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib,
1120+
@Bind PythonContext context,
11201121
@Bind("this") Node inliningTarget,
11211122
@Cached("createFor(this)") IndirectCallData indirectCallData,
11221123
@Cached CodecsModuleBuiltins.HandleDecodingErrorNode handleDecodingErrorNode,
@@ -1155,10 +1156,10 @@ Object generic(VirtualFrame frame, Object wSource, Object wFilename, TruffleStri
11551156
flags |= code.getFlags() & PyCF_MASK;
11561157
}
11571158

1158-
if (AstModuleBuiltins.isAst(getContext(), wSource)) {
1159-
ModTy mod = AstModuleBuiltins.obj2sst(getContext(), wSource, getParserInputType(mode, flags));
1159+
if (AstModuleBuiltins.isAst(context, wSource)) {
1160+
ModTy mod = AstModuleBuiltins.obj2sst(context, wSource, getParserInputType(mode, flags));
11601161
Source source = PythonUtils.createFakeSource(filename);
1161-
RootCallTarget rootCallTarget = getLanguage().compileForBytecodeInterpreter(getContext(), mod, source, false, optimize, null, null, flags);
1162+
RootCallTarget rootCallTarget = context.getLanguage(inliningTarget).compileForBytecodeInterpreter(context, mod, source, false, optimize, null, null, flags);
11621163
return wrapRootCallTarget(rootCallTarget, factory);
11631164
}
11641165
TruffleString source = sourceAsString(frame, inliningTarget, wSource, filename, interopLib, acquireLib, bufferLib, handleDecodingErrorNode, asStrNode, switchEncodingNode, factory,
@@ -1404,8 +1405,8 @@ static boolean doRecursiveWithLoop(VirtualFrame frame, Object instance, PTuple c
14041405
@Cached("createFor(this)") IndirectCallData indirectCallData,
14051406
@Shared @Cached GetObjectArrayNode getObjectArrayNode,
14061407
@Cached("createNonRecursive()") RecursiveBinaryCheckBaseNode node) {
1407-
PythonLanguage language = PythonLanguage.get(inliningTarget);
14081408
PythonContext context = PythonContext.get(inliningTarget);
1409+
PythonLanguage language = context.getLanguage(inliningTarget);
14091410
Object state = IndirectCallContext.enter(frame, language, context, indirectCallData);
14101411
try {
14111412
// Note: we need actual recursion to trigger the stack overflow error like CPython
@@ -2497,7 +2498,7 @@ protected Object doItNonFunction(VirtualFrame frame, Object function, Object[] a
24972498

24982499
PythonContext ctx = PythonContext.get(calculateMetaClass);
24992500
Env env = ctx.getEnv();
2500-
PythonLanguage language = PythonLanguage.get(inliningTarget);
2501+
PythonLanguage language = ctx.getLanguage(inliningTarget);
25012502
if (arguments.length == 2 && env.isHostObject(arguments[1]) && env.asHostObject(arguments[1]) instanceof Class<?>) {
25022503
// we want to subclass a Java class
25032504
return buildJavaClass(frame, language, (PFunction) function, arguments, factory, callBody, name);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsModuleBuiltins.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -1531,12 +1531,14 @@ protected ArgumentClinicProvider getArgumentClinic() {
15311531

15321532
@Specialization(limit = "3")
15331533
Object doIt(VirtualFrame frame, Object data, TruffleString errors, Object mapping,
1534+
@Bind("this") Node inliningTarget,
1535+
@Bind PythonContext context,
15341536
@Cached("createFor(this)") IndirectCallData indirectCallData,
15351537
@CachedLibrary("data") PythonBufferAcquireLibrary bufferAcquireLib,
15361538
@CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib,
15371539
@Cached PyUnicodeDecodeCharmapNode pyUnicodeDecodeCharmapNode,
15381540
@Cached PythonObjectFactory factory) {
1539-
Object dataBuffer = bufferAcquireLib.acquireReadonly(data, frame, getContext(), getLanguage(), indirectCallData);
1541+
Object dataBuffer = bufferAcquireLib.acquireReadonly(data, frame, context, context.getLanguage(inliningTarget), indirectCallData);
15401542
int len;
15411543
try {
15421544
len = bufferLib.getBufferLength(dataBuffer);

0 commit comments

Comments
 (0)