com.strobel.expressions.RuntimeOperations Maven / Gradle / Ivy
/*
* RuntimeOperations.java
*
* Copyright (c) 2012 Mike Strobel
*
* This source code is based on the Dynamic Language Runtime from Microsoft,
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0.
* A copy of the license can be found in the License.html file at the root of this distribution.
* By using this source code in any fashion, you are agreeing to be bound by the terms of the
* Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*/
package com.strobel.expressions;
import com.strobel.core.IStrongBox;
import com.strobel.util.ContractUtils;
/**
* @author Mike Strobel
*/
public final class RuntimeOperations {
private RuntimeOperations() {
throw ContractUtils.unreachable();
}
public static IRuntimeVariables createRuntimeVariables(final Object[] data, final long[] indexes) {
return new RuntimeVariableList(data, indexes);
}
private final static class RuntimeVariableList implements IRuntimeVariables {
//
// The top level environment. It contains pointers to parent
// environments, which are always in the first element.
//
private final Object[] _data;
//
// An array of (int, int) pairs, each representing how to find a
// variable in the environment data structure.
//
// The first integer indicates the number of times to go up in the
// closure chain, the second integer indicates the index into that
// closure chain.
//
private final long[] _indexes;
RuntimeVariableList(final Object[] data, final long[] indexes) {
assert (data != null);
assert (indexes != null);
_data = data;
_indexes = indexes;
}
public int size() {
return _indexes.length;
}
public Object get(final int index) {
return getStrongBox(index).get();
}
public void set(final int index, final Object value) {
getStrongBox(index).set(value);
}
private IStrongBox getStrongBox(final int index) {
//
// We lookup the closure using two integers:
// 1) The high dword is the number of parents to go up
// 2) The low dword is the index into that array
//
final long closureKey = _indexes[index];
//
// Walk up the parent chain to find the real environment.
//
Object[] result = _data;
for (int parents = (int)(closureKey >> 32); parents > 0; parents--) {
result = HoistedLocals.getParent(result);
}
//
// Return the variable storage.
//
return (IStrongBox)result[(int)closureKey];
}
}
}