blob: f3cd9dbadf6b65dc8b3e8b9db19ca35606f396b3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Intel, George A. Timoshenko
*
*/
#ifndef _BYTECODEPARSER_H_
#define _BYTECODEPARSER_H_
#include <assert.h>
#include "open/types.h"
namespace Jitrino {
class ByteCodeParserCallback {
public:
virtual ~ByteCodeParserCallback() {}
// parses one byte code starting at given offset,
// updates nextOffset to point at next byte code,
// returns false if parsing should stop
virtual bool parseByteCode(const U_8* byteCodes,U_32 byteCodeOffset) = 0;
// called before the parsing starts
virtual void parseInit() = 0;
// called after the parsing ends, but not if an error occurs
virtual void parseDone() = 0;
// if a callback during its construction determines some error
// the parsing can be ommitted with help of this:
virtual bool skipParsing() {return false;};
// called when an error occurs during the byte code parsing
virtual void parseError() = 0;
U_32 getNextOffset() {return nextOffset;}
protected:
U_32 nextOffset;
};
class ByteCodeParser {
public:
//
// creates a new ByteCodeParser
//
ByteCodeParser(const U_8* bc, U_32 length) {
byteCodes = bc; byteCodeLength = length; byteCodeOffset = 0;
}
//
// parses the byte code stream, makes calls to the ByteCodeParserCallback
//
void parse(ByteCodeParserCallback* cb) {
cb->parseInit();
if (!cb->skipParsing()) {
byteCodeOffset = 0;
while (byteCodeOffset < byteCodeLength) {
if (cb->parseByteCode(byteCodes,byteCodeOffset) != true) {
return;
}
byteCodeOffset = cb->getNextOffset();
}
}
cb->parseDone();
}
// Export these values to implement translator optimizations
const U_8* getByteCodes() {return byteCodes;}
U_32 getByteCodeLength() {return byteCodeLength;}
private:
const U_8* byteCodes;
U_32 byteCodeLength;
U_32 byteCodeOffset;
};
//
// byte code parsing utilities
//
#define readU4Le(bytes) (((U_32)(bytes)[3]<<24) | ((U_32)(bytes)[2]<<16) | \
((U_32)(bytes)[1]<<8) | (bytes)[0])
#define readU4Be(bytes) (((U_32)(bytes)[0]<<24) | ((U_32)(bytes)[1]<<16) | \
((U_32)(bytes)[2]<<8) | (bytes)[3])
inline I_8 si8(const U_8* bcp) {return ((I_8*)bcp)[0];}
inline U_8 su8(const U_8* bcp) {return bcp[0];}
inline float sr4(const U_8* bcp) {return ((float*)bcp)[0];}
inline double sr8(const U_8* bcp) {return ((double*)bcp)[0];}
} //namespace Jitrino
#endif // _BYTECODEPARSER_H_