-
Notifications
You must be signed in to change notification settings - Fork 125
Initial impl of BytecodeIonReader #1136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+2,570
−13
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
614 changes: 607 additions & 7 deletions
614
src/main/java/com/amazon/ion/bytecode/BytecodeIonReader.kt
Large diffs are not rendered by default.
Oops, something went wrong.
145 changes: 145 additions & 0 deletions
145
src/main/java/com/amazon/ion/bytecode/EncodingContextManager.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| package com.amazon.ion.bytecode | ||
|
|
||
| import com.amazon.ion.bytecode.util.BytecodeBuffer | ||
| import com.amazon.ion.bytecode.util.ConstantPool | ||
| import com.amazon.ion.ion_1_1.MacroImpl | ||
| import edu.umd.cs.findbugs.annotations.SuppressFBWarnings | ||
|
|
||
| /** | ||
| * TODO: | ||
| * Write more documentation. | ||
| * Implement stubbed out methods. | ||
| * | ||
| * Notes: | ||
| * | ||
| * It is never safe to remove or modify any existing data in the effective tables. It is safe to append data to those | ||
| * tables for an `add_symbols`, `add_macros`, or `use` directive (as long as the active encoding modules are just `$ion` and `_`). | ||
| */ | ||
| internal class EncodingContextManager { | ||
|
|
||
| companion object { | ||
| val SYSTEM_SYMBOLS = arrayOf( | ||
| null, | ||
| "\$ion", | ||
| "\$ion_1_0", | ||
| "\$ion_symbol_table", | ||
| "name", | ||
| "version", | ||
| "imports", | ||
| "symbols", | ||
| "max_id", | ||
| "\$ion_shared_symbol_table", | ||
| ) | ||
| } | ||
|
|
||
| // These make up the effective macro table and effective symbol table | ||
| private var macroBytecode = BytecodeBuffer() | ||
| private var macroOffsets = BytecodeBuffer() | ||
| private var macroNames = ConstantPool() | ||
| private var symbols = mutableListOf<String?>().apply { SYSTEM_SYMBOLS.forEach { add(it) } } | ||
|
|
||
| // TODO: Do we need the constant pool here? | ||
| private var constants = ConstantPool() | ||
|
|
||
| private class Module( | ||
| val symbols: Array<String>, | ||
| val macros: Array<MacroImpl>, | ||
| val macroNames: Array<String?> | ||
| ) | ||
|
|
||
| // Tracks only modules _other_ than the system module and default module | ||
| private val additionalAvailableModules = mutableMapOf<String, Module>() | ||
| // Tracks only modules _other_ than the system module and default module | ||
| private var additionalActiveModules = mutableListOf<Module>() | ||
|
|
||
| @SuppressFBWarnings("IE_EXPOSE_REP", justification = "array is accessible for performance") | ||
| fun getEffectiveMacroTableBytecode(): IntArray = macroBytecode.unsafeGetArray() | ||
|
|
||
| @SuppressFBWarnings("IE_EXPOSE_REP", justification = "array is accessible for performance") | ||
| fun getEffectiveMacroTableOffsets(): IntArray = macroOffsets.unsafeGetArray() | ||
|
|
||
| fun getEffectiveSymbolTable(): Array<String?> = symbols.toTypedArray() | ||
|
|
||
| @SuppressFBWarnings("IE_EXPOSE_REP", justification = "array is accessible for performance") | ||
| fun getEffectiveConstantPool(): Array<Any?> = constants.unsafeGetArray() | ||
|
|
||
| /** Called when encountering an IVM */ | ||
| fun reset() { | ||
| additionalActiveModules.clear() | ||
| additionalAvailableModules.clear() | ||
| macroBytecode.clear() | ||
| macroOffsets.clear() | ||
| macroNames.clear() | ||
| symbols.clear() | ||
| SYSTEM_SYMBOLS.forEach { symbols.add(it) } | ||
| constants.clear() | ||
| } | ||
|
|
||
| /** | ||
| * The [BytecodeIonReader] should be positioned in the directive, but not on the first value yet. | ||
| * When this method returns, the [BytecodeIonReader] will be positioned at the end of the directive, but not stepped out. | ||
| */ | ||
| fun readSetSymbolsDirective(reader: BytecodeIonReader) { | ||
| TODO() | ||
| } | ||
|
|
||
| /** | ||
| * The [BytecodeIonReader] should be positioned in the directive, but not on the first value yet. | ||
| * When this method returns, the [BytecodeIonReader] will be positioned at the end of the directive, but not stepped out. | ||
| */ | ||
| fun readAddSymbols(reader: BytecodeIonReader) { | ||
| TODO() | ||
| } | ||
|
|
||
| /** | ||
| * The [BytecodeIonReader] should be positioned in the directive, but not on the first value yet. | ||
| * When this method returns, the [BytecodeIonReader] will be positioned at the end of the directive, but not stepped out. | ||
| */ | ||
| fun readSetMacrosDirective(reader: BytecodeIonReader) { | ||
| TODO() | ||
| } | ||
|
|
||
| /** | ||
| * The [BytecodeIonReader] should be positioned in the directive, but not on the first value yet. | ||
| * When this method returns, the [BytecodeIonReader] will be positioned at the end of the directive, but not stepped out. | ||
| */ | ||
| fun readAddMacrosDirective(reader: BytecodeIonReader) { | ||
| TODO() | ||
| } | ||
|
|
||
| /** | ||
| * The [BytecodeIonReader] should be positioned in the directive, but not on the first value yet. | ||
| * When this method returns, the [BytecodeIonReader] will be positioned at the end of the directive, but not stepped out. | ||
| */ | ||
| fun readUseDirective(reader: BytecodeIonReader) { | ||
| TODO("Shared symbol tables and shared modules not supported yet.") | ||
| } | ||
|
|
||
| /** | ||
| * The [BytecodeIonReader] should be positioned in the directive, but not on the first value yet. | ||
| * When this method returns, the [BytecodeIonReader] will be positioned at the end of the directive, but not stepped out. | ||
| */ | ||
| fun readModuleDirective(reader: BytecodeIonReader) { | ||
| TODO("Module definitions not supported yet.") | ||
| } | ||
|
|
||
| /** | ||
| * The [BytecodeIonReader] should be positioned in the directive, but not on the first value yet. | ||
| * When this method returns, the [BytecodeIonReader] will be positioned at the end of the directive, but not stepped out. | ||
| */ | ||
| fun readImportDirective(reader: BytecodeIonReader) { | ||
| TODO("Shared symbol tables and shared modules not supported yet.") | ||
| } | ||
|
|
||
| /** | ||
| * The [BytecodeIonReader] should be positioned in the directive, but not on the first value yet. | ||
| * When this method returns, the [BytecodeIonReader] will be positioned at the end of the directive, but not stepped out. | ||
| * | ||
| * Content should be a list of module names, as symbols. | ||
| */ | ||
| fun readEncodingDirective(reader: BytecodeIonReader) { | ||
| TODO() | ||
| } | ||
| } |
46 changes: 46 additions & 0 deletions
46
src/main/java/com/amazon/ion/bytecode/ScalarConversionHelper.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| package com.amazon.ion.bytecode | ||
|
|
||
| import com.amazon.ion.Decimal | ||
| import com.amazon.ion.impl._Private_ScalarConversions | ||
| import com.amazon.ion.impl._Private_ScalarConversions.ValueVariant | ||
| import java.math.BigInteger | ||
|
|
||
| /** | ||
| * Wraps [_Private_ScalarConversions] to cut down on repeated code in [BytecodeIonReader]. | ||
| * | ||
| * This abstraction probably adds overhead, but it should only be used in the non-ideal paths—performing **lossy** | ||
| * conversions on scalar values. | ||
| */ | ||
| internal class ScalarConversionHelper { | ||
| private val scalarConverter = ValueVariant() | ||
| private val preparedConverter = ThisPreparedConverter() | ||
|
|
||
| private inline fun initConversion(startType: Int, addValueFn: ValueVariant.() -> Unit): PreparedConverter { | ||
| val converter = scalarConverter | ||
| converter.clear() | ||
| converter.addValueFn() | ||
| converter.authoritativeType = startType | ||
| return preparedConverter | ||
| } | ||
|
|
||
| fun from(value: Int) = initConversion(_Private_ScalarConversions.AS_TYPE.int_value) { addValue(value) } | ||
| fun from(value: Long) = initConversion(_Private_ScalarConversions.AS_TYPE.long_value) { addValue(value) } | ||
| fun from(value: BigInteger?) = initConversion(_Private_ScalarConversions.AS_TYPE.bigInteger_value) { addValue(value) } | ||
| fun from(value: Double) = initConversion(_Private_ScalarConversions.AS_TYPE.double_value) { addValue(value) } | ||
| fun from(value: Decimal?) = initConversion(_Private_ScalarConversions.AS_TYPE.decimal_value) { addValue(value) } | ||
|
|
||
| sealed class PreparedConverter(private val converter: ValueVariant) { | ||
|
|
||
| private fun doConversion(toType: Int): ValueVariant = converter.apply { cast(get_conversion_fnid(toType)) } | ||
|
|
||
| fun intoInt(): Int = doConversion(_Private_ScalarConversions.AS_TYPE.int_value).int | ||
| fun intoLong(): Long = doConversion(_Private_ScalarConversions.AS_TYPE.long_value).long | ||
| fun intoBigInteger(): BigInteger = doConversion(_Private_ScalarConversions.AS_TYPE.bigInteger_value).bigInteger | ||
| fun intoDecimal(): Decimal = doConversion(_Private_ScalarConversions.AS_TYPE.decimal_value).decimal | ||
| fun intoDouble(): Double = doConversion(_Private_ScalarConversions.AS_TYPE.double_value).double | ||
| } | ||
|
|
||
| private inner class ThisPreparedConverter : PreparedConverter(this@ScalarConversionHelper.scalarConverter) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it makes sense to have a separate END_INVOKE if you already have a separate END_TEMPLATE, but I'm pretty indifferent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but I've left a TODO because I think we can defer this until we are exposing un-evaluated macro invocations.