com.oracle.truffle.js.nodes.JSNodeDecoder Maven / Gradle / Ivy
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to any
* person obtaining a copy of this software, associated documentation and/or
* data (collectively the "Software"), free of charge and under any and all
* copyright rights in the Software, and any and all patent rights owned or
* freely licensable by each licensor hereunder covering either (i) the
* unmodified Software as contributed to or provided by such licensor, or (ii)
* the Larger Works (as defined below), to deal in both
*
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
* one is included with the Software each a "Larger Work" to which the Software
* is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy, create
* derivative works of, display, perform, and distribute the Software and make,
* use, sell, offer for sale, import, export, have made, and have sold the
* Software and the Larger Work(s), and to sublicense the foregoing rights on
* either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or at a
* minimum a reference to the UPL must be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.oracle.truffle.js.nodes;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.FrameSlotKind;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.strings.TruffleString;
import com.oracle.truffle.js.codec.BinaryDecoder;
import com.oracle.truffle.js.codec.NodeDecoder;
import com.oracle.truffle.js.nodes.control.BreakTarget;
import com.oracle.truffle.js.nodes.control.ContinueTarget;
import com.oracle.truffle.js.runtime.BigInt;
import com.oracle.truffle.js.runtime.JSContext;
import com.oracle.truffle.js.runtime.builtins.JSFunctionData;
import com.oracle.truffle.js.runtime.objects.Dead;
import com.oracle.truffle.js.runtime.objects.Null;
import com.oracle.truffle.js.runtime.objects.Undefined;
public class JSNodeDecoder {
public enum Bytecode {
ID_NOP,
/** Create node using factory method. */
ID_NODE,
/** Return result. */
ID_RETURN,
/** Load integer constant into register. */
ID_LDC_INT,
/** Load long constant into register. */
ID_LDC_LONG,
/** Load boolean constant into register. */
ID_LDC_BOOLEAN,
/** Load double constant into register. */
ID_LDC_DOUBLE,
/** Load enum constant into register. */
ID_LDC_ENUM,
/** Load string constant into register. */
ID_LDC_STRING,
/** Load string constant into register. */
ID_LDC_JAVA_STRING,
/** Load singleton constant into register. */
ID_LDC_SINGLETON,
/** Load BigInt constant into register. */
ID_LDC_BIGINT,
/** Load argument into register. */
ID_LD_ARG,
/** Move register to register. */
ID_MOV,
/** Create dynamic array from registers. */
ID_COLLECT_ARRAY,
/** Create ArrayList from registers. */
ID_COLLECT_LIST,
/** Create CallTarget. */
ID_CALL_TARGET,
/** Create FrameDescriptor. */
ID_FRAME_DESCRIPTOR,
/** Add FrameSlot to FrameDescriptor. */
ID_JSFRAME_SLOT,
/** Create SourceSection. */
ID_SOURCE_SECTION,
/** Create JSFunctionData. */
ID_FUNCTION_DATA,
/** Fix up JSFunctionData. */
ID_FUNCTION_DATA_NAME_FIXUP,
/** Create {@link BreakTarget} or {@link ContinueTarget}. */
ID_JUMP_TARGET,
ID_CALL_EXTRACTED,
ID_CALL_EXTRACTED_LAZY,
ID_NODE_SOURCE_SECTION_FIXUP,
ID_NODE_TAGS_FIXUP;
static final Bytecode[] bcValues = values();
}
public static final int BREAK_TARGET_LABEL = 1;
public static final int BREAK_TARGET_SWITCH = 2;
public static final int CONTINUE_TARGET_LOOP = 3;
public static final int CONTINUE_TARGET_UNLABELED_LOOP = 4;
public static final int CONTEXT_ARG = -1;
public static final int SOURCE_ARG = -2;
private static final boolean VERBOSE = false;
private static final NodeDecoder GEN = NodeFactoryDecoderGen.create();
private static final Object[] SINGLETONS = new Object[]{null, Undefined.instance, Null.instance, Dead.instance()};
public static int getSingletonIndex(Object singleton) {
return Arrays.asList(SINGLETONS).indexOf(singleton);
}
public static int getChecksum() {
return GEN.getChecksum();
}
public Object decodeNode(NodeDecoder.DecoderState state, NodeFactory nodeFactory, JSContext context, Source source) {
while (state.hasRemaining()) {
Bytecode bc = Bytecode.bcValues[state.getBytecode()];
switch (bc) {
case ID_NOP:
break;
case ID_NODE: {
Object node = GEN.decodeNode(state, nodeFactory);
int dest = state.getReg();
if (dest >= 0) {
state.setObjReg(dest, node);
}
break;
}
case ID_RETURN:
return state.getObject();
case ID_LDC_INT:
storeResult(state, state.getInt());
break;
case ID_LDC_LONG:
storeResult(state, state.getLong());
break;
case ID_LDC_BOOLEAN:
storeResult(state, state.getBoolean());
break;
case ID_LDC_DOUBLE:
storeResult(state, state.getDouble());
break;
case ID_LDC_ENUM:
storeResult(state, GEN.getClasses()[state.getInt()].getEnumConstants()[state.getInt()]);
break;
case ID_LDC_STRING:
storeResult(state, state.getString());
break;
case ID_LDC_JAVA_STRING:
storeResult(state, state.getString().toJavaStringUncached());
break;
case ID_LDC_SINGLETON:
storeResult(state, SINGLETONS[state.getInt()]);
break;
case ID_LDC_BIGINT:
storeResult(state, BigInt.valueOf(state.getString().toJavaStringUncached()));
break;
case ID_MOV:
state.setObjReg(state.getReg(), state.getObjReg(state.getReg()));
break;
case ID_LD_ARG:
int argIndex = state.getInt();
Object argument;
if (argIndex == CONTEXT_ARG) {
argument = context;
} else if (argIndex == SOURCE_ARG) {
argument = source;
} else {
assert argIndex >= 0 : argIndex;
argument = state.getArgument(argIndex);
}
storeResult(state, argument);
break;
case ID_COLLECT_ARRAY: {
int componentTypeIndex = state.getInt();
int length = state.getInt();
Object array = Array.newInstance(GEN.getClasses()[componentTypeIndex], length);
if (array instanceof Object[]) {
Object[] objArray = (Object[]) array;
for (int i = 0; i < length; i++) {
Object value = state.getObject();
objArray[i] = value;
}
} else {
for (int i = 0; i < length; i++) {
Object value = state.getObject();
Array.set(array, i, value);
}
}
storeResult(state, array);
break;
}
case ID_COLLECT_LIST: {
int length = state.getInt();
ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy