Skip to content

Instantly share code, notes, and snippets.

@UplinkCoder
Last active August 6, 2016 18:24
Show Gist options
  • Select an option

  • Save UplinkCoder/57f3fbab99ae4e2ba84dbe77490387a5 to your computer and use it in GitHub Desktop.

Select an option

Save UplinkCoder/57f3fbab99ae4e2ba84dbe77490387a5 to your computer and use it in GitHub Desktop.
BCBuilitin_NextUTF8CharT nextChar = (const Heap* heapPtr, uint* argPtr) pure {
uint stringPos = *argPtr;
uint stringPosOverFour = stringPos / 4;
uint bytePos = stringPos % 4;
uint loWord = heapPtr._heap[stringPosOverFour];
uint c = intrin_Byte3(loWord, bytePos);
if (!((cast(ubyte)c) & 0x80)) {
(*argPtr) = stringPos + 1;
return BCValue(Imm32(c));
} else {
//TODO check for invalid sequences!
if ((c & 0b0010_0000) == 0) { // we have a 2byte sequence
if (bytePos++ == 3) { // probability for this is 1/4;
c |= (intrin_Byte3(heapPtr._heap[++stringPosOverFour], 0) & 0x80) >> 5;
} else {
c |= (intrin_Byte3(loWord, bytePos) & 0x80) >> 5;
}
(*argPtr) = stringPos + 2;
} else if ((c & 0b0001_0000) == 0) { // we have a 3 byte sequence
if (bytePos++ == 3) { // probability for this is 1/4;
uint hiWord = heapPtr._heap[++stringPosOverFour];
c |= (intrin_Byte3(hiWord, 0) & 0x80) >> 4;
c |= (intrin_Byte3(hiWord, 1) & 0x80) >> (4+6);
} else {
c |= (intrin_Byte3(loWord, bytePos++) & 0x7f) >> 4;
if (bytePos++ == 3) { // the probabilty for this is 2/4
c |= (intrin_Byte3(heapPtr._heap[++stringPosOverFour], 0) & 0x7f) >> (4+6);
}
}
(*argPtr) = stringPos + 3;
} else {
//TODO when we support more the 3 chars cache the hi-word;
assert(0, "For now we don't support UTF8 Chars bigger then 3");
}
return(BCValue(Imm32(c)));
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment