示例#1
0
/*JSON{ "type":"function", "name" : "trace", "ifndef" : "SAVE_ON_FLASH",
         "description" : "Output debugging information",
         "generate" : "jswrap_interface_trace",
         "params" : [ [ "root", "JsVar", "The symbol to output (optional). If nothing is specified, everything will be output"] ]
}*/
void jswrap_interface_trace(JsVar *root) {
  if (jsvIsUndefined(root)) {
    jsvTrace(jsvGetRef(execInfo.root), 0);
  } else {
    jsvTrace(jsvGetRef(root), 0);
  }
}
/*JSON{ "type":"function", "name" : "trace", "ifndef" : "SAVE_ON_FLASH",
         "description" : "Output debugging information",
         "generate" : "jswrap_interface_trace",
         "params" : [ [ "root", "JsVarName", "The symbol to output (optional). If nothing is specified, everything will be output"] ]
}*/
void jswrap_interface_trace(JsVar *root) {
  if (jsvIsUndefined(root)) {
    jsvTrace(jsvGetRef(jsiGetParser()->root), 0);
  } else {
    jsvTrace(jsvGetRef(root), 0);
  }
}
示例#3
0
void jsvStringIteratorAppend(JsvStringIterator *it, char ch) {
  if (!it->var) return;
  if (it->charsInVar>0) {
    assert(it->charIdx+1 == it->charsInVar /* check at end */);
    it->charIdx++;
  } else
    assert(it->charIdx == 0);
  if (it->charIdx >= jsvGetMaxCharactersInVar(it->var)) {
    assert(!jsvGetLastChild(it->var));
    JsVar *next = jsvNewWithFlags(JSV_STRING_EXT_0);
    if (!next) {
      jsvUnLock(it->var);
      it->var = 0;
      it->charIdx = 0;
      return; // out of memory
    }
    // we don't ref, because  StringExts are never reffed as they only have one owner (and ALWAYS have an owner)
    jsvSetLastChild(it->var, jsvGetRef(next));
    jsvUnLock(it->var);
    it->var = next;
    it->varIndex += it->charIdx;
    it->charIdx = 0; // it's new, so empty
  }
  it->var->varData.str[it->charIdx] = ch;
  it->charsInVar = it->charIdx+1;
  jsvSetCharactersInVar(it->var, it->charsInVar);
}
示例#4
0
void jsvStringIteratorAppend(JsvStringIterator *it, char ch) {
  if (!it->var) return;
  if (it->charsInVar>0) {
    assert(it->charIdx+1 == it->charsInVar /* check at end */);
    it->charIdx++;
  } else
    assert(it->charIdx == 0);
  /* Note: jsvGetMaxCharactersInVar will return the wrong length when
   * applied to flat strings, but we don't care because the length will
   * be smaller than charIdx, which will force a new string to be
   * appended onto the end  */
  if (it->charIdx >= jsvGetMaxCharactersInVar(it->var)) {
    assert(!jsvGetLastChild(it->var));
    JsVar *next = jsvNewWithFlags(JSV_STRING_EXT_0);
    if (!next) {
      jsvUnLock(it->var);
      it->var = 0;
      it->ptr = 0;
      it->charIdx = 0;
      return; // out of memory
    }
    // we don't ref, because  StringExts are never reffed as they only have one owner (and ALWAYS have an owner)
    jsvSetLastChild(it->var, jsvGetRef(next));
    jsvUnLock(it->var);
    it->var = next;
    it->ptr = &next->varData.str[0];
    it->varIndex += it->charIdx;
    it->charIdx = 0; // it's new, so empty
  }
  it->ptr[it->charIdx] = ch;
  it->charsInVar = it->charIdx+1;
  jsvSetCharactersInVar(it->var, it->charsInVar);
}
示例#5
0
文件: jslex.c 项目: CWBudde/Espruino
JsVar *jslNewStringFromLexer(JslCharPos *charFrom, size_t charTo) {
  // Original method - just copy it verbatim
  size_t maxLength = charTo + 1 - jsvStringIteratorGetIndex(&charFrom->it);
  assert(maxLength>0); // will fail if 0
  // Try and create a flat string first
  JsVar *var = 0;
  if (maxLength > JSV_FLAT_STRING_BREAK_EVEN) {
    var = jsvNewFlatStringOfLength((unsigned int)maxLength);
    if (var) {
      // Flat string
      char *flatPtr = jsvGetFlatStringPointer(var);
      *(flatPtr++) = charFrom->currCh;
      JsvStringIterator it = jsvStringIteratorClone(&charFrom->it);
      while (jsvStringIteratorHasChar(&it) && (--maxLength>0)) {
        *(flatPtr++) = jsvStringIteratorGetChar(&it);
        jsvStringIteratorNext(&it);
      }
      jsvStringIteratorFree(&it);
      return var;
    }
  }
  // Non-flat string...
  var = jsvNewFromEmptyString();
  if (!var) { // out of memory
    return 0;
  }

  //jsvAppendStringVar(var, lex->sourceVar, charFrom->it->index, (int)(charTo-charFrom));
  JsVar *block = jsvLockAgain(var);
  block->varData.str[0] = charFrom->currCh;
  size_t blockChars = 1;

  size_t l = maxLength;
  // now start appending
  JsvStringIterator it = jsvStringIteratorClone(&charFrom->it);
  while (jsvStringIteratorHasChar(&it) && (--maxLength>0)) {
    char ch = jsvStringIteratorGetChar(&it);
    if (blockChars >= jsvGetMaxCharactersInVar(block)) {
      jsvSetCharactersInVar(block, blockChars);
      JsVar *next = jsvNewWithFlags(JSV_STRING_EXT_0);
      if (!next) break; // out of memory
      // we don't ref, because  StringExts are never reffed as they only have one owner (and ALWAYS have an owner)
      jsvSetLastChild(block, jsvGetRef(next));
      jsvUnLock(block);
      block = next;
      blockChars=0; // it's new, so empty
    }
    block->varData.str[blockChars++] = ch;
    jsvStringIteratorNext(&it);
  }
  jsvSetCharactersInVar(block, blockChars);
  jsvUnLock(block);
  // Just make sure we only assert if there's a bug here. If we just ran out of memory or at end of string it's ok
  assert((l == jsvGetStringLength(var)) || (jsErrorFlags&JSERR_MEMORY) || !jsvStringIteratorHasChar(&it));
  jsvStringIteratorFree(&it);


  return var;
}
示例#6
0
JsVar *jswrap_typedarray_constructor(JsVarDataArrayBufferViewType type, JsVar *arr, JsVarInt byteOffset, JsVarInt length) {
  JsVar *arrayBuffer = 0;
  // Only allow use of byteOffset/length if we're passing an ArrayBuffer - NOT A VIEW.
  bool copyData = false;
  if (jsvIsArrayBuffer(arr) && arr->varData.arraybuffer.type==ARRAYBUFFERVIEW_ARRAYBUFFER) {
    arrayBuffer = jsvLockAgain(arr);
  } else if (jsvIsNumeric(arr)) {
    length = jsvGetInteger(arr);
    byteOffset = 0;
    arrayBuffer = jswrap_arraybuffer_constructor((int)JSV_ARRAYBUFFER_GET_SIZE(type)*length);
  } else if (jsvIsArray(arr) || jsvIsArrayBuffer(arr)) {
    length = (JsVarInt)jsvGetLength(arr);
    byteOffset = 0;
    arrayBuffer = jswrap_arraybuffer_constructor((int)JSV_ARRAYBUFFER_GET_SIZE(type)*length);
    copyData = true; // so later on we'll populate this
  }
  if (!arrayBuffer) {
    jsExceptionHere(JSET_ERROR, "Unsupported first argument of type %t\n", arr);
    return 0;
  }
  if (length==0) {
    length = ((JsVarInt)jsvGetArrayBufferLength(arrayBuffer)-byteOffset) / (JsVarInt)JSV_ARRAYBUFFER_GET_SIZE(type); 
    if (length<0) length=0;
  }
  JsVar *typedArr = jsvNewWithFlags(JSV_ARRAYBUFFER);
  if (typedArr) {
    typedArr->varData.arraybuffer.type = type;
    typedArr->varData.arraybuffer.byteOffset = (unsigned short)byteOffset;
    typedArr->varData.arraybuffer.length = (unsigned short)length;
    jsvSetFirstChild(typedArr, jsvGetRef(jsvRef(arrayBuffer)));

    if (copyData) {
      // if we were given an array, populate this ArrayBuffer
      JsvIterator it;
      jsvIteratorNew(&it, arr, JSIF_DEFINED_ARRAY_ElEMENTS);
      while (jsvIteratorHasElement(&it)) {
        JsVar *idx = jsvIteratorGetKey(&it);
        if (jsvIsInt(idx)) {
          JsVar *val = jsvIteratorGetValue(&it);
          // TODO: This is horrible! We need to try and iterate properly...
          jsvArrayBufferSet(typedArr, (size_t)jsvGetInteger(idx), val);
          jsvUnLock(val);
        }
        jsvUnLock(idx);
        jsvIteratorNext(&it);
      }
      jsvIteratorFree(&it);
    }
  }
  jsvUnLock(arrayBuffer);
  return typedArr;
}
示例#7
0
/*JSON{ "type":"idle", "generate" : "jswrap_waveform_idle", "ifndef" : "SAVE_ON_FLASH" }*/
bool jswrap_waveform_idle() {
  JsVar *waveforms = jsvObjectGetChild(execInfo.hiddenRoot, JSI_WAVEFORM_NAME, 0);
  if (waveforms) {
    JsvArrayIterator it;
    jsvArrayIteratorNew(&it, waveforms);
    while (jsvArrayIteratorHasElement(&it)) {
      JsVar *waveform = jsvArrayIteratorGetElement(&it);

      bool running = jsvGetBoolAndUnLock(jsvObjectGetChild(waveform, "running", 0));
      if (running) {
        JsVar *buffer = jswrap_waveform_getBuffer(waveform,0,0);
        UtilTimerTask task;
        // Search for a timer task
        if (!jstGetLastBufferTimerTask(buffer, &task)) {
          // if the timer task is now gone...
          JsVar *arrayBuffer = jsvObjectGetChild(waveform, "buffer", 0);
          jsiQueueObjectCallbacks(waveform, "#onfinish", &arrayBuffer, 1);
          jsvUnLock(arrayBuffer);
          running = false;
          jsvUnLock(jsvObjectSetChild(waveform, "running", jsvNewFromBool(running)));
        } else {
          // If the timer task is still there...
          if (task.data.buffer.nextBuffer &&
              task.data.buffer.nextBuffer != task.data.buffer.currentBuffer) {
            // if it is a double-buffered task
            int currentBuffer = (jsvGetRef(buffer)==task.data.buffer.currentBuffer) ? 0 : 1;
            JsVar *oldBuffer = jsvObjectGetChild(waveform, "currentBuffer", JSV_INTEGER);
            if (jsvGetInteger(oldBuffer) !=currentBuffer) {
              // buffers have changed - fire off a 'buffer' event with the buffer that needs to be filled
              jsvSetInteger(oldBuffer, currentBuffer);
              JsVar *arrayBuffer = jsvObjectGetChild(waveform, (currentBuffer==0) ? "buffer" : "buffer2", 0);
              jsiQueueObjectCallbacks(waveform, "#onbuffer", &arrayBuffer, 1);
              jsvUnLock(arrayBuffer);
            }
            jsvUnLock(oldBuffer);
          }
        }
        jsvUnLock(buffer);
      }
      jsvUnLock(waveform);
      // if not running, remove waveform from this list
      if (!running)
        jsvArrayIteratorRemoveAndGotoNext(&it, waveforms);
      else
        jsvArrayIteratorNext(&it);
    }
    jsvArrayIteratorFree(&it);
    jsvUnLock(waveforms);
  }
  return false; // no need to stay awake - an IRQ will wake us
}
JsVar *jswrap_typedarray_constructor(JsVarDataArrayBufferViewType type, JsVar *arr, JsVarInt byteOffset, JsVarInt length) {
  JsVar *arrayBuffer = 0;
  if (jsvIsArrayBuffer(arr)) {
    arrayBuffer = jsvLockAgain(arr);
  } else if (jsvIsInt(arr)) {
    length = jsvGetInteger(arr);
    byteOffset = 0;
    arrayBuffer = jswrap_arraybuffer_constructor(JSV_ARRAYBUFFER_GET_SIZE(type)*length);
  } else if (jsvIsArray(arr)) {
    length = jsvGetArrayLength(arr);
    byteOffset = 0;
    arrayBuffer = jswrap_arraybuffer_constructor(JSV_ARRAYBUFFER_GET_SIZE(type)*length);
    // later on we'll populate this
  }
  if (!arrayBuffer) {
    jsError("Unsupported first argument\n");
    return 0;
  }
  if (length<=0) length = (JsVarInt)jsvGetArrayBufferLength(arrayBuffer) / JSV_ARRAYBUFFER_GET_SIZE(type);
  JsVar *typedArr = jsvNewWithFlags(JSV_ARRAYBUFFER);
  if (typedArr) {
    typedArr->varData.arraybuffer.type = type;
    typedArr->varData.arraybuffer.byteOffset = (unsigned short)byteOffset;
    typedArr->varData.arraybuffer.length = (unsigned short)length;
    typedArr->firstChild = jsvGetRef(jsvRef(arrayBuffer));

    if (jsvIsArray(arr)) {
      // if we were given an array, populate this ArrayBuffer
      JsvArrayIterator it;
      jsvArrayIteratorNew(&it, arr);
      while (jsvArrayIteratorHasElement(&it)) {
        JsVar *idx = jsvArrayIteratorGetIndex(&it);
        if (jsvIsInt(idx)) {
          JsVar *val = jsvArrayIteratorGetElement(&it);
          jsvArrayBufferSet(typedArr, jsvGetInteger(idx), val);
          jsvUnLock(val);
        }
        jsvUnLock(idx);
        jsvArrayIteratorNext(&it);
      }
      jsvArrayIteratorFree(&it);
    }
  }
  jsvUnLock(arrayBuffer);
  return typedArr;
}
示例#9
0
bool run_test(const char *filename) {
  printf("----------------------------------\r\n");
  printf("----------------------------- TEST %s \r\n", filename);
  char *buffer = (char *)read_file(filename);
  if (!buffer) return (false);

  jshInit();
  jsiInit(false /* do not autoload!!! */);

  jspAddNativeFunction(jsiGetParser(), "function quit()", nativeQuit);
  jspAddNativeFunction(jsiGetParser(), "function interrupt()", nativeInterrupt);

  jsvUnLock(jspEvaluate(jsiGetParser(), buffer ));

  isRunning = true;
  while (isRunning && jsiHasTimers()) jsiLoop();

  JsVar *result = jsvObjectGetChild(jsiGetParser()->root, "result", 0/*no create*/);
  bool pass = jsvGetBool(result);
  jsvUnLock(result);

  if (pass)
    printf("----------------------------- PASS %s\r\n", filename);
  else {
    printf("----------------------------------\r\n");
    printf("----------------------------- FAIL %s <-------\r\n", filename);
    jsvTrace(jsvGetRef(jsiGetParser()->root), 0);
    printf("----------------------------- FAIL %s <-------\r\n", filename);
    printf("----------------------------------\r\n");
  }
  printf("BEFORE: %d Memory Records Used\r\n", jsvGetMemoryUsage());
 // jsvTrace(jsiGetParser()->root, 0);
  jsiKill();
  printf("AFTER: %d Memory Records Used\r\n", jsvGetMemoryUsage());
  jsvGarbageCollect();
  printf("AFTER GC: %d Memory Records Used (should be 0!)\r\n", jsvGetMemoryUsage());
  jsvShowAllocated();
  jshKill();

  //jsvDottyOutput();
  printf("\r\n");

  free(buffer);
  return pass;
}
示例#10
0
JsVar *_jswrap_array_map_or_forEach(JsVar *parent, JsVar *funcVar, JsVar *thisVar, bool isMap) {
  if (!jsvIsFunction(funcVar)) {
    jsError("Array.map's first argument should be a function");
    return 0;
  }
  if (!jsvIsUndefined(thisVar) && !jsvIsObject(thisVar)) {
    jsError("Arraymap's second argument should be undefined, or an object");
    return 0;
  }
  JsVar *array = 0;
  if (isMap)
    array = jsvNewWithFlags(JSV_ARRAY);
  if (array || !isMap) {
   JsVarRef childRef = parent->firstChild;
   while (childRef) {
     JsVar *child = jsvLock(childRef);
     if (jsvIsInt(child)) {
       JsVar *args[3], *mapped;
       args[0] = jsvLock(child->firstChild);
       // child is a variable name, create a new variable for the index
       args[1] = jsvNewFromInteger(jsvGetInteger(child));
       args[2] = parent;
       mapped = jspeFunctionCall(funcVar, 0, thisVar, false, 3, args);
       jsvUnLock(args[0]);
       jsvUnLock(args[1]);
       if (mapped) {
         if (isMap) {
           JsVar *name = jsvCopyNameOnly(child, false/*linkChildren*/, true/*keepAsName*/);
           if (name) { // out of memory?
             name->firstChild = jsvGetRef(jsvRef(mapped));
             jsvAddName(array, name);
             jsvUnLock(name);
           }
         }
         jsvUnLock(mapped);
       }
     }
     childRef = child->nextSibling;
     jsvUnLock(child);
   }
  }
  return array;
}
/*JSON{ "type":"function", "name" : "edit",
        "description" : ["Fill the console with the contents of the given function, so you can edit it.",
                         "NOTE: This is a convenience function - it will not edit 'inner functions'. For that, you must edit the 'outer function' and re-execute it."],
        "generate" : "jswrap_interface_edit",
        "params" : [ [ "funcName", "JsVarName", "The name of the function to edit (either a string or just the unquoted name)"] ]
}*/
void jswrap_interface_edit(JsVar *funcName) {
  if (jsvIsString(funcName)) {
    JsVar *func = 0;
    if (jsvIsName(funcName))
      func = jsvSkipName(funcName);
    else
      func = jsvSkipNameAndUnLock(jsvFindChildFromVar(jsiGetParser()->root, funcName, 0));
    if (jsvIsFunction(func)) {
      JsVar *scopeVar = jsvFindChildFromString(func, JSPARSE_FUNCTION_SCOPE_NAME, false);
      JsVarRef scope = jsvGetRef(scopeVar);
      jsvUnLock(scopeVar);
      JsVar *newLine = jsvNewFromEmptyString();
      if (newLine) { // could be out of memory
        jsvAppendStringVarComplete(newLine, funcName);
        if (scope) {
          // If we have a scope, it's an internal function so we will need to write different code
          jsvAppendString(newLine, ".replaceWith(");
        } else {
          jsvAppendString(newLine, " = ");
        }
        JsVar *funcData = jsvAsString(func, false);
        if (funcData)
          jsvAppendStringVarComplete(newLine, funcData);
        jsvUnLock(funcData);
        if (scope) {
          jsvAppendString(newLine, ");");
        } else {
          jsvAppendString(newLine, ";");
        }
        jsiReplaceInputLine(newLine);
        jsvUnLock(newLine);
      }
    } else {
      jsError("Edit should be called with the name of a function");
    }
    jsvUnLock(func);
  } else {
    jsError("Edit should be called with edit(funcName) or edit('funcName')");
  }
}
示例#12
0
/*JSON{ "type":"constructor", "class": "ArrayBuffer",  "name": "ArrayBuffer",
         "description" : "Create an Array Buffer object",
         "generate" : "jswrap_arraybuffer_constructor",
         "params" : [ [ "byteLength", "int", "The length in Bytes" ] ],
         "return" : [ "JsVar", "An ArrayBuffer object" ]

}*/
JsVar *jswrap_arraybuffer_constructor(JsVarInt byteLength) {
  if (byteLength <= 0 || byteLength>65535) {
    jsError("Invalid length for ArrayBuffer\n");
    return 0;
  }
  if (byteLength > JSV_ARRAYBUFFER_MAX_LENGTH) {
    jsError("ArrayBuffer too long\n");
    return 0;
  }
  JsVar *arrData = jsvNewStringOfLength((unsigned int)byteLength);
  if (!arrData) return 0;
  JsVar *arr = jsvNewWithFlags(JSV_ARRAYBUFFER);
  if (!arr) {
    jsvUnLock(arrData);
    return 0;
  }
  arr->firstChild = jsvGetRef(jsvRef(arrData));
  jsvUnLock(arrData);
  arr->varData.arraybuffer.type = ARRAYBUFFERVIEW_ARRAYBUFFER;
  arr->varData.arraybuffer.byteOffset = 0;
  arr->varData.arraybuffer.length = (unsigned short)byteLength;
  return arr;
}
示例#13
0
JsVar *jslNewFromLexer(struct JsLex *lex, JslCharPos *charFrom, size_t charTo) {
  // Create a var
  JsVar *var = jsvNewFromEmptyString();
  if (!var) { // out of memory
    return 0;
  }

  //jsvAppendStringVar(var, lex->sourceVar, charFrom->it->index, (int)(charTo-charFrom));
  size_t maxLength = charTo - jsvStringIteratorGetIndex(&charFrom->it);
  JsVar *block = jsvLockAgain(var);
  block->varData.str[0] = charFrom->currCh;
  size_t blockChars = 1;

  // now start appending
  JsvStringIterator it = jsvStringIteratorClone(&charFrom->it);
  while (jsvStringIteratorHasChar(&it) && (maxLength-->0)) {
    char ch = jsvStringIteratorGetChar(&it);
    if (blockChars >= jsvGetMaxCharactersInVar(block)) {
      jsvSetCharactersInVar(block, blockChars);
      JsVar *next = jsvNewWithFlags(JSV_STRING_EXT);
      if (!next) break; // out of memory
      // we don't ref, because  StringExts are never reffed as they only have one owner (and ALWAYS have an owner)
      block->lastChild = jsvGetRef(next);
      jsvUnLock(block);
      block = next;
      blockChars=0; // it's new, so empty
    }
    block->varData.str[blockChars++] = ch;
    jsvStringIteratorNext(&it);
  }
  jsvStringIteratorFree(&it);
  jsvSetCharactersInVar(block, blockChars);
  jsvUnLock(block);

  return var;
}