You are not logged in.
Pages: 1
Please check now. Now I've removed constructors and implemented a virtual function GetSecureProtocols, which can be overridden in descedants
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
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
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)
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
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
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;
isObject is property of jsval. Fixed in example.
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
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;
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;
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
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.
Pages: 1