#1 Re: mORMot 1 » TWinHTTP with custom Security protocols » 2021-09-17 12:52:12

Please check now. Now I've removed constructors and implemented a virtual function GetSecureProtocols, which can be overridden in descedants

#2 mORMot 1 » TWinHTTP with custom Security protocols » 2021-09-17 09:13:00

Orel
Replies: 2

I need to limit security protocols on client side(e.g. allow only TLS 1.2 and reject all others)
Here is my suggestion how to implement it.
https://github.com/synopse/mORMot/pull/406

#3 Re: SyNode » How to return an array of JSON object... » 2018-11-16 13:13:09

mrluis, this solution is risky
You must make fld rooted before using it

            fld := cx.NewRootedObject(cx.NewObject(nil));
 
            try
                for fldCount := 0 to FQuery.FieldCount -1 do begin
                  fldName  := LowerCase(FQuery.Fields[fldCount].FieldName);
                  fldValue := FQuery.Fields[fldCount].AsString;

                  fld.ptr.SetProperty(cx, PAnsiChar(fldName), SimpleVariantToJSval(cx,fldValue)) ;// <-------------you have chance to get AV here if garbage collector will start work
                end;

                arr.ptr.SetElement(cx, loop, fld.ptr.ToJSValue);
            finally
              cx.FreeRootedObject(fld );
            end;

In opposite case garbage collector can move fld to another place in memory and you will get AV
Garbage collecting can start in any moment

#4 Re: SyNode » Beta release of SyNode - ES6 JavaScript + NPM modules » 2018-04-24 11:57:38

I am not sure than ChakraCore is faster than SpiderMonkey.
In one my project I used a lot of float operation (3D rendering + design) in browser
Calculation in FireFox and chrome took the same time, but calculation in Edge took  2-3 times more time
I cannot say anything about object and properties(test needed)

#5 Re: SyNode » Beta release of SyNode - ES6 JavaScript + NPM modules » 2017-09-05 07:15:02

George wrote:

Need little help, i get strange results while debugging Debugger.js.
...
I use output log to debug Debugger.js, is better way exists?

consoleLog(JSON.stringify(source)); // -> {}

is usual behavior for internal debugger's objects
We used for debug debugger

consoleLog(stringify(source.<propertyName>));

List of properties you can see on MDN
But I am not sure that information on that page is actual, so I recommend You see also source code

#6 Re: SyNode » Beta release of SyNode - ES6 JavaScript + NPM modules » 2017-08-29 07:22:10

George wrote:

Hi, mpv!

What is the best approach to add "console" emulation for JS context?
Should i create a class with all required methods, instantiate it and then call aEngine.GlobalObject.ptr.DefineProperty?
Is there a way to group few methods in one variable (like console.log, console.clear) without class instance on delphi side?
PS: dll extension can provide such behavior, but i'm interested to implement console internally.

The best idea is group them in *.js file(like nodejs does). You can see source code of node's console.js on GitHub
In this case you must implement some bindings. You can find examples of bindings in Synode code. Also you can find implementation of nodejs binding on GitHub and translate it to Delphy synode SpiderMonkey compatible code
If you will do this then sharing code to community will be a good idea

#7 Re: SyNode » Beta release of SyNode - ES6 JavaScript + NPM modules » 2016-10-31 09:44:15

ComingNine wrote:

Could you help to suggest how to code the JSNative function at Delphi side, to return array to JS side, which can be used with lodash ? Many thanks !

for normal Array

function <funcName>(cx: PJSContext; argc: uintN; var vp: jsargRec): Boolean; cdecl;
var arr: PJSRootedObject;
...
begin
  try
    ....
    arr := cx.NewRootedObject(cx.NewArrayObject(0));
    try
      arr.ptr.SetElement(cx, 0, SimpleVariantToJSval(cx, 'Some string'));
      arr.ptr.SetElement(cx, 1, SimpleVariantToJSval(cx, 25));
      arr.ptr.SetElement(cx, 2, SimpleVariantToJSval(cx, true));
      ...
      vp.rval := arr.ptr.ToJSValue;
    finally
      cx.FreeRootedObject(arr);
    end;
    Result := True;

  except
    on E: Exception do
    begin
      Result := False;
      vp.rval := JSVAL_VOID;
      JSError(cx, E);
    end;
  end;
end;

for Typed array(it is like delphi array - all elements has the same type but you can not change size of array after creation)

function <funcName>(cx: PJSContext; argc: uintN; var vp: jsargRec): Boolean; cdecl;
const arrSize = 50;
var arr: PJSRootedObject;
     arrData: Puint32Vector;
     i: integer;
     isShared: Boolean;
...
begin
  try
    ....
    arr := cx.NewRootedObject(cx.NewUint32Array(arrSize));
    try
      arrData := arr.GetUint32ArrayData(isShared, nil);
      for i := 0 to arrSize - 1 do
        arrData [i] := i*i;
      ...
      vp.rval := arr.ptr.ToJSValue;
    finally
      cx.FreeRootedObject(arr);
    end;
    Result := True;

  except
    on E: Exception do
    begin
      Result := False;
      vp.rval := JSVAL_VOID;
      JSError(cx, E);
    end;
  end;
end;

#8 Re: SyNode » Beta release of SyNode - ES6 JavaScript + NPM modules » 2016-10-19 09:36:15

isObject is property of jsval. Fixed in example.

ComingNine wrote:

It then seems that we could not get Delphi array directly from jsval but has to call ptr.GetElement(cx, index, jsArrElement); manually.

Yes, you are right.
JavaScript allow the next construction

var arr = [];
arr[5] = 5;
arr[770000001] = 100;

in this case arr.length is 770000002, but array has only 2 values. arr[4] or arr[77778] is undefined. SpiderMonkey do not allocate memory for other values. So, you can not get all values to delphi array directly. Array in JS and array in Delphi is not the same.
Dirrectly acces to values you can get if you use JavaScript typed array. But in this case you cannot change array dimension

#9 Re: SyNode » Beta release of SyNode - ES6 JavaScript + NPM modules » 2016-10-19 08:17:37

ComingNine wrote:

why the "jsval.asDouble" returns NaN for 0.0 and 1.0

SpiderMonkey stores number value in 2 ways: signed int32 or double. 0.0 or 1.0 is converts to int32 and you can not use it as double.

So for using number value you can use the next code

function TfrmSM45Demo.JSTestOnlyZeroAfterDecimal(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean;
var
  dblval: Double;
begin
  try
    if (argc = 0) or  not vp.argv[0].isNumber then
      raise ESMException.Create('Expectig argument number type ');
    if vp.argv[0].isDouble then
      dblval := vp.argv[0].asDouble
    else if vp.argv[0].isInteger then
      dblval := vp.argv[0].asInteger
    else
      raise ESMException.Create('This can never happen');
    mResult.Lines.Add('########    ' + FloatToStrF(dblval, ffFixed, 20, 8) + '   ########');
    Result := True;
  except
    on E: Exception do begin
      Result := False;
      vp.rval := JSVAL_VOID;
      JSError(cx, E);
    end;
  end;
end;

#10 Re: SyNode » Beta release of SyNode - ES6 JavaScript + NPM modules » 2016-10-19 08:07:17

ComingNine wrote:

why the "JSObject.Is***Array" returns false

functions JSObject.Is***Array uses for JavaScript typed arrays. Array is not JavaScript typed array, so this functions return false.

Also your using jsArr.isObject without rooting is not good idea - garbage collecting can start in any moment, so your jsArr.isObject in any moment can point to invalid address. Also you do not handle exception if it can throw. the right ussage is

function TfrmSM45Demo.JSTestArray1D(cx: PJSContext; argc: uintN; var vp: JSArgRec): Boolean;
var
  jsArrElement: jsval;
  jsArr: PJSRootedObject;
  Cnt, I: Cardinal;
begin
  try
    mResult.Lines.Add('###########################');
    mResult.Lines.Add(BoolToStr(vp.argv[0].isObject, True));
    jsArr := cx.NewRootedObject(vp.argv[0].asObject);
    try
      mResult.Lines.Add(BoolToStr(jsArr.ptr.isArray(cx), True));
      mResult.Lines.Add(BoolToStr(jsArr.ptr.IsTypedArrayObject, True));
      mResult.Lines.Add(BoolToStr(jsArr.ptr.IsInt8Array, True));
      mResult.Lines.Add(BoolToStr(jsArr.ptr.IsUInt8Array, True));
      mResult.Lines.Add(BoolToStr(jsArr.ptr.IsInt16Array, True));
      mResult.Lines.Add(BoolToStr(jsArr.ptr.IsUInt16Array, True));
      mResult.Lines.Add(BoolToStr(jsArr.ptr.IsInt32Array, True));
      mResult.Lines.Add(BoolToStr(jsArr.ptr.IsUInt32Array, True));
      mResult.Lines.Add(BoolToStr(jsArr.ptr.IsFloat32Array, True));
      mResult.Lines.Add(BoolToStr(jsArr.ptr.IsFloat64Array, True));
      mResult.Lines.Add('---------------------------');
      jsArr.ptr.GetArrayLength(cx, Cnt);
      mResult.Lines.Add(IntToStr(Cnt));
      jsArr.ptr.GetElement(cx, 0, jsArrElement);
      mResult.Lines.Add(BoolToStr(jsArrElement.isInteger, True));
      mResult.Lines.Add(BoolToStr(jsArrElement.isDouble, True));
      mResult.Lines.Add(BoolToStr(jsArrElement.isNumber, True));
      mResult.Lines.Add(BoolToStr(jsArrElement.isSimpleVariant[cx], True));
      mResult.Lines.Add('###########################');
    finally
      cx.FreeRootedObject(jsArr);
    end;
    Result := True;
  except
    on E: Exception do begin
      Result := False;
      vp.rval := JSVAL_VOID;
      JSError(cx, E);
    end;
  end;
end;

#11 Re: mORMot 1 » Pass classes to Javascript » 2016-08-26 17:45:54

Yes. It is possible. See  SyNode/Samples/02 - Bindings for sample. In this sample main form is binded to js
But don't forget than you can work with js engine only in the same thread in what it was created. In opposite case you can get av

#12 Re: SyNode » Adding JavaScript support for mORMot framework » 2014-11-20 13:52:37

You shouldn't. TSMObject is not instance of class. It is not allocated in heap but in a stack. You do not allocate memory for it so you shouldn't free it. JS object will be freed by the garbage collector when the reference count on it become equal to 0.

Board footer

Powered by FluxBB